#include <sys/cdefs.h>
#include <dev/pms/config.h>
#include <dev/pms/freebsd/driver/common/osenv.h>
#include <dev/pms/freebsd/driver/common/ostypes.h>
#include <dev/pms/freebsd/driver/common/osdebug.h>
#include <dev/pms/RefTisa/sallsdk/api/sa.h>
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
#include <dev/pms/RefTisa/tisa/api/titypes.h>
#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
#ifdef FDS_SM
#include <dev/pms/RefTisa/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
#endif
#ifdef FDS_DM
#include <dev/pms/RefTisa/discovery/api/dm.h>
#include <dev/pms/RefTisa/discovery/api/dmapi.h>
#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
#include <dev/pms/freebsd/driver/common/osstring.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
#ifdef INITIATOR_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
#endif
#ifdef TARGET_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
osGLOBAL bit32
tiINIDiscoverTargets(
tiRoot_t *tiRoot,
tiPortalContext_t *portalContext,
bit32 option
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *PortContextList;
tdsaPortContext_t *onePortContext = agNULL;
bit32 found = agFALSE;
#ifdef FDS_DM
dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
dmPortContext_t *dmPortContext = agNULL;
#endif
TI_DBG3(("tiINIDiscoverTargets: start\n"));
TI_DBG6(("tiINIDiscoverTargets: portalContext %p\n", portalContext));
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
TI_DBG1(("tiINIDiscoverTargets: No tdsaPortContext\n"));
return tiError;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
PortContextList = tdsaAllShared->MainPortContextList.flink;
if (PortContextList == agNULL)
{
TI_DBG1(("tiINIDiscoverTargets: PortContextList is NULL\n"));
return tiError;
}
while (PortContextList != &(tdsaAllShared->MainPortContextList))
{
onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
if (onePortContext == agNULL)
{
TI_DBG1(("tiINIDiscoverTargets: onePortContext is NULL, PortContextList = %p\n", PortContextList));
return tiError;
}
if (onePortContext->tiPortalContext == portalContext && onePortContext->valid == agTRUE)
{
TI_DBG6(("tiINIDiscoverTargets: found; oneportContext ID %d\n", onePortContext->id));
found = agTRUE;
break;
}
PortContextList = PortContextList->flink;
}
if (found == agFALSE)
{
TI_DBG1(("tiINIDiscoverTargets: No corresponding tdsaPortContext\n"));
return tiError;
}
TI_DBG2(("tiINIDiscoverTargets: pid %d\n", onePortContext->id));
if (onePortContext->DiscoveryState == ITD_DSTATE_NOT_STARTED)
{
TI_DBG6(("tiINIDiscoverTargets: calling Discovery\n"));
#ifdef FDS_DM
if (onePortContext->UseDM == agTRUE)
{
TI_DBG1(("tiINIDiscoverTargets: calling dmDiscover, pid %d\n", onePortContext->id));
onePortContext->DiscoveryState = ITD_DSTATE_STARTED;
dmPortContext = &(onePortContext->dmPortContext);
dmDiscover(dmRoot, dmPortContext, DM_DISCOVERY_OPTION_FULL_START);
}
else
{
onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
ostiInitiatorEvent(
tiRoot,
portalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscOK,
agNULL
);
return tiSuccess;
}
#else
#ifdef TD_DISCOVER
tdsaDiscover(
tiRoot,
onePortContext,
AG_SA_DISCOVERY_TYPE_SAS,
TDSA_DISCOVERY_OPTION_FULL_START
);
#else
saDiscover(onePortContext->agRoot, onePortContext->agPortContext, AG_SA_DISCOVERY_TYPE_SAS, onePortContext->discoveryOptions);
#endif
#endif
}
else
{
TI_DBG1(("tiINIDiscoverTargets: Discovery has started or incorrect initialization; state %d pid 0x%x\n",
onePortContext->DiscoveryState,
onePortContext->id));
return tiError;
}
return tiSuccess;
}
osGLOBAL bit32
tiINIGetDeviceHandles(
tiRoot_t * tiRoot,
tiPortalContext_t * tiPortalContext,
tiDeviceHandle_t * tiDev[],
bit32 maxDevs
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *PortContextList;
tdsaPortContext_t *onePortContext = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
bit32 i;
bit32 FoundDevices = 0;
bit32 DeviceIndex = 0;
bit32 found = agFALSE;
#ifdef TD_DEBUG_ENABLE
satDeviceData_t *pSatDevData;
#endif
#ifdef FDS_DM
dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
#endif
TI_DBG2(("tiINIGetDeviceHandles: start\n"));
TI_DBG2(("tiINIGetDeviceHandles: tiPortalContext %p\n", tiPortalContext));
if (maxDevs == 0)
{
TI_DBG1(("tiINIGetDeviceHandles: maxDevs is 0\n"));
TI_DBG1(("tiINIGetDeviceHandles: first, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
TI_DBG1(("tiINIGetDeviceHandles: No available tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandles: second, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
PortContextList = tdsaAllShared->MainPortContextList.flink;
while (PortContextList != &(tdsaAllShared->MainPortContextList))
{
onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
if(onePortContext == agNULL) continue;
TI_DBG3(("tiINIGetDeviceHandles: oneportContext pid %d\n", onePortContext->id));
if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
{
TI_DBG3(("tiINIGetDeviceHandles: found; oneportContext pid %d\n", onePortContext->id));
found = agTRUE;
break;
}
PortContextList = PortContextList->flink;
}
if (found == agFALSE)
{
TI_DBG1(("tiINIGetDeviceHandles: First, No corresponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandles: third, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext == agNULL)
{
TI_DBG1(("tiINIGetDeviceHandles: Second, No corressponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandles: fourth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tiINIGetDeviceHandles: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetDeviceHandles: fifth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed)
{
TI_DBG1(("tiINIGetDeviceHandles: forth, discovery failed, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetDeviceHandles: sixth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
{
TI_DBG1(("tiINIGetDeviceHandles: discovery not completed\n"));
TI_DBG1(("tiINIGetDeviceHandles: sixth, returning DISCOVERY_IN_PROGRESS, pid %d\n", onePortContext->id));
onePortContext->discovery.forcedOK = agTRUE;
return DISCOVERY_IN_PROGRESS;
}
TI_DBG2(("tiINIGetDeviceHandles: pid %d\n", onePortContext->id));
#ifdef FDS_DM
tdsaUpdateMCN(dmRoot, onePortContext);
#endif
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
TD_ASSERT(DeviceListList, "DeviceListList NULL");
if (DeviceListList == agNULL )
{
TI_DBG1(("tiINIGetDeviceHandles: DeviceListList == agNULL\n"));
TI_DBG1(("tiINIGetDeviceHandles: seventh, returning not found, pid %d\n", onePortContext->id));
return 0;
}
while ((DeviceIndex < maxDevs) &&
DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
#ifdef TD_DEBUG_ENABLE
pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData);
if (pSatDevData != agNULL)
{
TI_DBG3(("tiINIGetDeviceHandles: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
TI_DBG3(("tiINIGetDeviceHandles: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
}
#endif
TI_DBG3(("tiINIGetDeviceHandles: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
TI_DBG3(("tiINIGetDeviceHandles: device AddrHi 0x%08x AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG6(("tiINIGetDeviceHandles: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
if (oneDeviceData->tdPortContext != onePortContext)
{
TI_DBG3(("tiINIGetDeviceHandles: different port\n"));
DeviceListList = DeviceListList->flink;
}
else
{
#ifdef SATA_ENABLE
if ((oneDeviceData->valid == agTRUE) &&
(oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)
|| DEVICE_IS_SATA_DEVICE(oneDeviceData) )
)
#else
if ((oneDeviceData->valid == agTRUE) &&
(oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) )
)
#endif
{
if (DEVICE_IS_SSP_TARGET(oneDeviceData))
{
TI_DBG2(("tiINIGetDeviceHandles: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
FoundDevices++;
}
else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
&&
oneDeviceData->satDevData.IDDeviceValid == agTRUE )
{
TI_DBG2(("tiINIGetDeviceHandles: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
FoundDevices++;
}
else
{
TI_DBG3(("tiINIGetDeviceHandles: skip case !!!\n"));
TI_DBG3(("tiINIGetDeviceHandles: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData)));
TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->satDevData.IDDeviceValid %d\n", oneDeviceData->satDevData.IDDeviceValid));
TI_DBG3(("tiINIGetDeviceHandles: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext)));
TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext));
}
TI_DBG3(("tiINIGetDeviceHandles: valid FoundDevices %d\n", FoundDevices));
TI_DBG3(("tiINIGetDeviceHandles: agDevHandle %p\n", oneDeviceData->agDevHandle));
}
else
{
TI_DBG3(("tiINIGetDeviceHandles: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData)));
TI_DBG3(("tiINIGetDeviceHandles: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext)));
TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext));
}
DeviceIndex++;
DeviceListList = DeviceListList->flink;
}
}
if (DeviceIndex > maxDevs)
{
TI_DBG1(("tiINIGetDeviceHandles: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs));
FoundDevices = maxDevs;
}
TI_DBG1(("tiINIGetDeviceHandles: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id));
return FoundDevices;
}
osGLOBAL bit32
tiINIGetDeviceHandlesForWinIOCTL(
tiRoot_t * tiRoot,
tiPortalContext_t * tiPortalContext,
tiDeviceHandle_t * tiDev[],
bit32 maxDevs
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *PortContextList;
tdsaPortContext_t *onePortContext = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
bit32 i;
bit32 FoundDevices = 0;
bit32 DeviceIndex = 0;
bit32 found = agFALSE;
#ifdef TD_DEBUG_ENABLE
satDeviceData_t *pSatDevData;
#endif
#ifdef FDS_DM
dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
#endif
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: start\n"));
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: tiPortalContext %p\n", tiPortalContext));
if (maxDevs == 0)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: maxDevs is 0\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: first, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: No available tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: second, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
PortContextList = tdsaAllShared->MainPortContextList.flink;
while (PortContextList != &(tdsaAllShared->MainPortContextList))
{
onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
if(onePortContext == agNULL) continue;
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneportContext pid %d\n", onePortContext->id));
if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
{
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: found; oneportContext pid %d\n", onePortContext->id));
found = agTRUE;
break;
}
PortContextList = PortContextList->flink;
}
if (found == agFALSE)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: First, No corresponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: third, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext == agNULL)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: Second, No corressponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: fourth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: fifth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: forth, discovery failed, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: sixth, returning 0\n"));
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
return 0;
}
if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: discovery not completed\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: sixth, returning DISCOVERY_IN_PROGRESS, pid %d\n", onePortContext->id));
onePortContext->discovery.forcedOK = agTRUE;
return DISCOVERY_IN_PROGRESS;
}
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: pid %d\n", onePortContext->id));
#ifdef FDS_DM
tdsaUpdateMCN(dmRoot, onePortContext);
#endif
for (i = 0 ; i < maxDevs ; i++)
{
tiDev[i] = agNULL;
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
TD_ASSERT(DeviceListList, "DeviceListList NULL");
if (DeviceListList == agNULL )
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceListList == agNULL\n"));
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: seventh, returning not found, pid %d\n", onePortContext->id));
return 0;
}
while ((DeviceIndex < maxDevs) &&
DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if(oneDeviceData == agNULL)
{
TI_DBG3(("tiINIGetDeviceHandles: OneDeviceData is NULL\n"));
return 0;
}
#ifdef TD_DEBUG_ENABLE
pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData);
if (pSatDevData != agNULL)
{
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
}
#endif
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device AddrHi 0x%08x AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG6(("tiINIGetDeviceHandlesForWinIOCTL: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
if (oneDeviceData->tdPortContext != onePortContext)
{
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: different port\n"));
DeviceListList = DeviceListList->flink;
}
else
{
#ifdef SATA_ENABLE
if ((oneDeviceData->valid == agTRUE) &&
(oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)
|| DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData))
)
#else
if ((oneDeviceData->valid == agTRUE) &&
(oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
)
#endif
{
if (DEVICE_IS_SSP_TARGET(oneDeviceData))
{
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
DeviceIndex++;
FoundDevices++;
}
else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
&&
oneDeviceData->satDevData.IDDeviceValid == agTRUE )
{
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
DeviceIndex++;
FoundDevices++;
}
else if (DEVICE_IS_SMP_TARGET(oneDeviceData))
{
TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SMP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
DeviceIndex++;
FoundDevices++;
}
else
{
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: skip case !!!\n"));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData)));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->satDevData.IDDeviceValid %d\n", oneDeviceData->satDevData.IDDeviceValid));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext)));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext));
}
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid FoundDevices %d\n", FoundDevices));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: agDevHandle %p\n", oneDeviceData->agDevHandle));
}
else
{
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData)));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext)));
TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext));
}
DeviceListList = DeviceListList->flink;
}
}
if (DeviceIndex > maxDevs)
{
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs));
FoundDevices = maxDevs;
}
TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id));
return FoundDevices;
}
osGLOBAL bit32
tiINIGetDeviceInfo(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle,
tiDeviceInfo_t *tiDeviceInfo)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
satDeviceData_t *pSatDevData = agNULL;
bit8 id_limit[5];
bit8 SN_id_limit[25];
agsaRoot_t *agRoot = agNULL;
TI_DBG6(("tiINIGetDeviceInfo: start \n"));
if (tiDeviceHandle == agNULL)
{
TI_DBG6(("tiINIGetDeviceInfo: tiDeviceHandle NULL\n"));
return tiInvalidHandle;
}
if (tiDeviceHandle->tdData == agNULL)
{
TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NULL\n"));
return tiInvalidHandle;
}
else
{
oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData);
agRoot = oneDeviceData->agRoot;
TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NOT NULL\n"));
}
if (oneDeviceData == agNULL)
{
TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ oneDeviceData NULL\n"));
return tiInvalidHandle;
}
if (oneDeviceData->registered == agTRUE)
{
tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
}
else
{
tiDeviceInfo->info.devType_S_Rate = (bit8)(oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f);
}
if (DEVICE_IS_SATA_DEVICE(oneDeviceData) && (oneDeviceData->directlyAttached == agTRUE))
{
osti_memset(&id_limit, 0, sizeof(id_limit));
osti_memset(&SN_id_limit, 0, sizeof(SN_id_limit));
id_limit[0] = 0xA;
id_limit[1] = 0xB;
id_limit[2] = 0xC;
id_limit[3] = 0xD;
pSatDevData = &(oneDeviceData->satDevData);
if (pSatDevData->satNCQ == agTRUE)
{
id_limit[4] = (bit8)pSatDevData->satNCQMaxIO;
}
else
{
id_limit[4] = 1;
}
osti_memcpy(&SN_id_limit, &(oneDeviceData->satDevData.satIdentifyData.serialNumber), 20);
osti_memcpy(&(SN_id_limit[20]), &id_limit, 5);
osti_memcpy(oneDeviceData->satDevData.SN_id_limit, SN_id_limit, 25);
tiDeviceInfo->remoteName = (char *)oneDeviceData->satDevData.SN_id_limit;
tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber);
tiDeviceInfo->osAddress1 = 25;
tiDeviceInfo->osAddress2 = 40;
}
else if (DEVICE_IS_STP_TARGET(oneDeviceData))
{
tiDeviceInfo->remoteName = (char *)&(oneDeviceData->satDevData.satIdentifyData.serialNumber);
tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber);
tiDeviceInfo->osAddress1 = 20;
tiDeviceInfo->osAddress2 = 40;
}
else
{
tiDeviceInfo->remoteName = (char *)&(oneDeviceData->SASAddressID.sasAddressHi);
tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->SASAddressID.sasAddressLo);
TI_DBG1(("tiINIGetDeviceInfo: SAS device remote hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasRemoteAddressHi, oneDeviceData->tdPortContext->sasRemoteAddressLo));
tiDeviceInfo->osAddress1 = 4;
tiDeviceInfo->osAddress2 = 4;
}
tiDeviceInfo->localName = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi);
tiDeviceInfo->localAddress = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo);
TI_DBG6(("tiINIGetDeviceInfo: local hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasLocalAddressHi, oneDeviceData->tdPortContext->sasLocalAddressLo));
if (oneDeviceData->agDevHandle == agNULL)
{
TI_DBG1(("tiINIGetDeviceInfo: Error! oneDeviceData->agDevHandle is NULL"));
return tiError;
}
else
{
saGetDeviceInfo(agRoot, agNULL, 0, 0,oneDeviceData->agDevHandle);
}
return tiSuccess;
}
osGLOBAL bit32
tiINILogin(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle
)
{
TI_DBG6(("tiINILogin: start\n"));
return tiNotSupported;
}
osGLOBAL bit32
tiINILogout(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle
)
{
TI_DBG6(("tiINILogout: start\n"));
return tiNotSupported;
}
osGLOBAL bit32
tiINIGetExpander(
tiRoot_t * tiRoot,
tiPortalContext_t * tiPortalContext,
tiDeviceHandle_t * tiDev,
tiDeviceHandle_t ** tiExp
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *PortContextList;
tdsaPortContext_t *onePortContext = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaDeviceData_t *oneTargetDeviceData = agNULL;
tdsaDeviceData_t *oneExpanderDeviceData = agNULL;
bit32 found = agFALSE;
oneTargetDeviceData = (tdsaDeviceData_t *)tiDev->tdData;
if (oneTargetDeviceData == agNULL)
{
TI_DBG1(("tiINIGetExpander: oneTargetDeviceData is NULL\n"));
return tiError;
}
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
TI_DBG1(("tiINIGetExpander: No available tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpander: second, returning 0\n"));
return tiError;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
PortContextList = tdsaAllShared->MainPortContextList.flink;
while (PortContextList != &(tdsaAllShared->MainPortContextList))
{
onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
TI_DBG3(("tiINIGetExpander: oneportContext pid %d\n", onePortContext->id));
if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
{
TI_DBG3(("tiINIGetExpander: found; oneportContext pid %d\n", onePortContext->id));
found = agTRUE;
break;
}
PortContextList = PortContextList->flink;
}
if (found == agFALSE)
{
TI_DBG1(("tiINIGetExpander: First, No corresponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpander: third, returning 0\n"));
return tiError;
}
if (onePortContext == agNULL)
{
TI_DBG1(("tiINIGetExpander: Second, No corressponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpander: fourth, returning 0\n"));
return tiError;
}
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tiINIGetExpander: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetExpander: fifth, returning 0\n"));
return tiError;
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while ( DeviceListList != &(tdsaAllShared->MainDeviceList) )
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData->tdPortContext != onePortContext)
{
TI_DBG3(("tiINIGetExpander: different port\n"));
DeviceListList = DeviceListList->flink;
}
else
{
if (oneDeviceData == oneTargetDeviceData)
{
oneExpanderDeviceData = oneDeviceData->ExpDevice;
if (oneExpanderDeviceData == agNULL)
{
TI_DBG1(("tiINIGetExpander: oneExpanderDeviceData is NULL\n"));
return tiError;
}
*tiExp = &(oneExpanderDeviceData->tiDeviceHandle);
return tiSuccess;
}
DeviceListList = DeviceListList->flink;
}
}
return tiError;
}
osGLOBAL void tiIniGetDirectSataSasAddr(tiRoot_t * tiRoot, bit32 phyId, bit8 **sasAddressHi, bit8 **sasAddressLo)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
agsaRoot_t *agRoot = &tdsaAllShared->agRootInt;
tiIOCTLPayload_wwn_t agIoctlPayload;
bit8 nvmDev;
bit32 status;
int i;
agIoctlPayload.Length = 4096;
agIoctlPayload.Reserved = 0;
agIoctlPayload.MinorFunction = IOCTL_MN_NVMD_GET_CONFIG;
agIoctlPayload.MajorFunction = IOCTL_MJ_NVMD_GET;
tiCOMDelayedInterruptHandler(tiRoot, 0,1, tiNonInterruptContext);
if(tiIS_SPC(agRoot))
{
nvmDev = 4;
status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev);
}
else
{
nvmDev = 1;
status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev);
}
if(status == IOCTL_CALL_FAIL)
{
#if !(defined(__FreeBSD__))
printk("Error getting Adapter WWN\n");
#else
printf("Error getting Adapter WWN\n");
#endif
return;
}
for(i=0; i< TD_MAX_NUM_PHYS; i++)
{
*(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressHi) = *(bit32 *)&agIoctlPayload.FunctionSpecificArea[0];
*(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressLo) = *(bit32 *)&agIoctlPayload.FunctionSpecificArea[4];
TI_DBG3(("SAS AddressHi is 0x%x\n", *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressHi)));
TI_DBG3(("SAS AddressLo is 0x%x\n", *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressLo)));
}
*sasAddressHi = tdsaAllShared->Ports[phyId].SASID.sasAddressHi;
*sasAddressLo = tdsaAllShared->Ports[phyId].SASID.sasAddressLo;
}
osGLOBAL tiDeviceHandle_t *
tiINIGetExpDeviceHandleBySasAddress(
tiRoot_t * tiRoot,
tiPortalContext_t * tiPortalContext,
bit32 sas_addr_hi,
bit32 sas_addr_lo,
bit32 maxDevs
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *PortContextList;
tdsaPortContext_t *onePortContext = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
bit32 DeviceIndex = 0;
bit32 found = agFALSE;
TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: start\n"));
TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: tiPortalContext %p\n", tiPortalContext));
if (maxDevs == 0)
{
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: maxDevs is 0\n"));
return agNULL;
}
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: No available tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: second, returning 0\n"));
return agNULL;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
PortContextList = tdsaAllShared->MainPortContextList.flink;
if(PortContextList == agNULL)
{
TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: PortContextList is NULL!!\n"));
return agNULL;
}
while (PortContextList != &(tdsaAllShared->MainPortContextList))
{
onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
if(onePortContext == agNULL)
{
TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: onePortContext is NULL!!\n"));
return agNULL;
}
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneportContext pid %d\n", onePortContext->id));
if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
{
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: found; oneportContext pid %d\n", onePortContext->id));
found = agTRUE;
break;
}
if(PortContextList != agNULL)
{
PortContextList = PortContextList->flink;
}
}
if (found == agFALSE)
{
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: First, No corresponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: third, returning 0\n"));
return agNULL;
}
if (onePortContext == agNULL)
{
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Second, No corressponding tdsaPortContext\n"));
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fourth, returning 0\n"));
return agNULL;
}
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fifth, returning 0\n"));
return agNULL;
}
TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: pid %d\n", onePortContext->id));
DeviceListList = tdsaAllShared->MainDeviceList.flink;
if(DeviceListList == agNULL)
{
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: DeviceListList == agNULL\n"));
TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: seventh, returning not found, pid %d\n", onePortContext->id));
return agNULL;
}
while ((DeviceIndex < maxDevs) &&
DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if(oneDeviceData == agNULL)
{
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneDeviceData is NULL!!\n"));
return agNULL;
}
TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
if (oneDeviceData->tdPortContext != onePortContext)
{
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: different port\n"));
if(DeviceListList != agNULL)
{
DeviceListList = DeviceListList->flink;
}
}
else
{
if ((oneDeviceData->valid == agTRUE) &&
(oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
(
(oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) ||
(oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) ||
DEVICE_IS_SMP_TARGET(oneDeviceData)
)
)
{
if(oneDeviceData->SASAddressID.sasAddressLo == sas_addr_lo && oneDeviceData->SASAddressID.sasAddressHi == sas_addr_hi)
{
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: agDevHandle %p\n", oneDeviceData->agDevHandle));
TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: Matched sas address: low %x and high %x\n", oneDeviceData->SASAddressID.sasAddressLo, oneDeviceData->SASAddressID.sasAddressHi));
return &(oneDeviceData->tiDeviceHandle);
}
}
DeviceIndex++;
DeviceListList = DeviceListList->flink;
}
}
return agNULL;
}
#ifdef TD_DISCOVER
osGLOBAL bit32
tdsaDiscover(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
bit32 type,
bit32 option
)
{
bit32 ret = tiError;
TI_DBG3(("tdsaDiscover: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaDiscover: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return ret;
}
switch ( option )
{
case TDSA_DISCOVERY_OPTION_FULL_START:
TI_DBG3(("tdsaDiscover: full\n"));
onePortContext->discovery.type = TDSA_DISCOVERY_OPTION_FULL_START;
if ( type == TDSA_DISCOVERY_TYPE_SAS )
{
ret = tdsaSASFullDiscover(tiRoot, onePortContext);
}
#ifdef SATA_ENABLE
else if ( type == TDSA_DISCOVERY_TYPE_SATA )
{
if (onePortContext->discovery.status == DISCOVERY_SAS_DONE)
{
ret = tdsaSATAFullDiscover(tiRoot, onePortContext);
}
}
#endif
break;
case TDSA_DISCOVERY_OPTION_INCREMENTAL_START:
TI_DBG3(("tdsaDiscover: incremental\n"));
onePortContext->discovery.type = TDSA_DISCOVERY_OPTION_INCREMENTAL_START;
if ( type == TDSA_DISCOVERY_TYPE_SAS )
{
TI_DBG3(("tdsaDiscover: incremental SAS\n"));
ret = tdsaSASIncrementalDiscover(tiRoot, onePortContext);
}
#ifdef SATA_ENABLE
else if ( type == TDSA_DISCOVERY_TYPE_SATA )
{
if (onePortContext->discovery.status == DISCOVERY_SAS_DONE)
{
TI_DBG3(("tdsaDiscover: incremental SATA\n"));
ret = tdsaSATAIncrementalDiscover(tiRoot, onePortContext);
}
}
#endif
break;
case TDSA_DISCOVERY_OPTION_ABORT:
TI_DBG1(("tdsaDiscover: abort\n"));
break;
default:
break;
}
if (ret != tiSuccess)
{
TI_DBG1(("tdsaDiscover: fail, error 0x%x\n", ret));
}
return ret;
}
osGLOBAL bit32
tdsaSASFullDiscover(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
int i, j;
bit8 portMaxRate;
TI_DBG3(("tdsaSASFullDiscover: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASFullDiscover: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return tiError;
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG3(("tdsaSASFullDiscover: STARTED loop id %d\n", oneDeviceData->id));
TI_DBG3(("tdsaSASFullDiscover: STARTED loop sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASFullDiscover: STARTED loop sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
if (oneDeviceData->tdPortContext == onePortContext &&
(onePortContext->nativeSATAMode == agFALSE && onePortContext->directAttatchedSAS == agFALSE) )
{
TI_DBG3(("tdsaSASFullDiscover: invalidate\n"));
oneDeviceData->valid = agFALSE;
oneDeviceData->processed = agFALSE;
}
else
{
TI_DBG3(("tdsaSASFullDiscover: not invalidate\n"));
}
DeviceListList = DeviceListList->flink;
}
onePortContext->DiscoveryState = ITD_DSTATE_STARTED;
if (onePortContext->nativeSATAMode == agFALSE)
{
if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE &&
SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) )
{
for(i=0;i<TD_MAX_NUM_PHYS;i++)
{
if (onePortContext->PhyIDList[i] == agTRUE)
{
for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++)
{
saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL);
}
break;
}
}
}
portMaxRate = onePortContext->LinkRate;
oneDeviceData = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
onePortContext->sasIDframe,
agFALSE,
portMaxRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
agNULL,
0xFF
);
if (oneDeviceData)
{
if (oneDeviceData->registered == agFALSE)
{
tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
}
else
{
tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
}
}
#ifdef REMOVED
tdsaReportManInfoSend(tiRoot, oneDeviceData);
#endif
}
else
{
tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
}
return tiSuccess;
}
osGLOBAL void
tdsaSASUpStreamDiscoverStart(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaExpander_t *oneExpander;
TI_DBG3(("tdsaSASUpStreamDiscoverStart: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASUpStreamDiscoverStart: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
onePortContext->discovery.status = DISCOVERY_UP_STREAM;
if (
(oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE)
||
(oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE)
)
{
oneExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, oneDeviceData);
if ( oneExpander != agNULL)
{
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
}
else
{
TI_DBG1(("tdsaSASUpStreamDiscoverStart: failed to allocate expander or discovey aborted\n"));
return;
}
}
tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
return;
}
osGLOBAL void
tdsaSASUpStreamDiscovering(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdList_t *ExpanderList;
tdsaExpander_t *oneNextExpander = agNULL;
TI_DBG3(("tdsaSASUpStreamDiscovering: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASUpStreamDiscovering: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdsaSASUpStreamDiscovering: should be the end\n"));
oneNextExpander = agNULL;
}
else
{
TDLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList));
oneNextExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList);
TDLIST_ENQUEUE_AT_HEAD(&(oneNextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList));
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdssSASDiscoveringExpander tdsaSASUpStreamDiscovering: dequeue head\n"));
TI_DBG3(("tdsaSASUpStreamDiscovering: expander id %d\n", oneNextExpander->id));
}
if (oneNextExpander != agNULL)
{
tdsaReportGeneralSend(tiRoot, oneNextExpander->tdDevice);
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscovering: No more expander list\n"));
tdsaSASDownStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
}
return;
}
osGLOBAL void
tdsaSASDownStreamDiscoverStart(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaExpander_t *oneExpander;
tdsaExpander_t *UpStreamExpander;
TI_DBG3(("tdsaSASDownStreamDiscoverStart: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASDownStreamDiscoverStart: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
TI_DBG3(("tdsaSASDownStreamDiscoverStart: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData));
if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE)
|| (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE))
{
oneExpander = oneDeviceData->tdExpander;
UpStreamExpander = oneExpander->tdUpStreamExpander;
if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->tdUpStreamExpander == oneExpander ) )
{
TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root found pExpander=%p pUpStreamExpander=%p\n",
oneExpander, UpStreamExpander));
onePortContext->discovery.RootExp = oneExpander;
TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
oneExpander->tdUpStreamExpander = agNULL;
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
UpStreamExpander->tdUpStreamExpander = agNULL;
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, UpStreamExpander);
}
else
{
onePortContext->discovery.RootExp = oneExpander;
TI_DBG3(("tdsaSASDownStreamDiscoverStart: NO Root pExpander=%p\n", oneExpander));
TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
}
}
tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
return;
}
osGLOBAL void
tdsaSASDownStreamDiscovering(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaExpander_t *NextExpander = agNULL;
tdList_t *ExpanderList;
TI_DBG3(("tdsaSASDownStreamDiscovering: start\n"));
TI_DBG3(("tdsaSASDownStreamDiscovering: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASDownStreamDiscovering: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdsaSASDownStreamDiscovering: should be the end\n"));
NextExpander = agNULL;
}
else
{
TDLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList));
NextExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList);
TDLIST_ENQUEUE_AT_HEAD(&(NextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList));
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdssSASDiscoveringExpander tdsaSASDownStreamDiscovering: dequeue head\n"));
TI_DBG3(("tdsaSASDownStreamDiscovering: expander id %d\n", NextExpander->id));
}
if ( NextExpander != agNULL)
{
TI_DBG3(("tdsaSASDownStreamDiscovering: Found pNextExpander=%p\n, discoveryStatus=0x%x",
NextExpander, onePortContext->discovery.status));
switch (onePortContext->discovery.status)
{
case DISCOVERY_DOWN_STREAM:
TI_DBG3(("tdsaSASDownStreamDiscovering: DownStream pNextExpander->pDevice=%p\n", NextExpander->tdDevice));
tdsaReportGeneralSend(tiRoot, NextExpander->tdDevice);
break;
case DISCOVERY_CONFIG_ROUTING:
case DISCOVERY_REPORT_PHY_SATA:
onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
TI_DBG3(("tdsaSASDownStreamDiscovering: pPort->discovery.status=DISCOVERY_CONFIG_ROUTING, nake it DOWN_STREAM\n"));
if ( NextExpander->discoveringPhyId < NextExpander->tdDevice->numOfPhys )
{
TI_DBG3(("tdsaSASDownStreamDiscovering: pNextExpander->discoveringPhyId=0x%x pNextExpander->pDevice->numOfPhys=0x%x. Send More Discover\n",
NextExpander->discoveringPhyId, NextExpander->tdDevice->numOfPhys));
tdsaDiscoverSend(tiRoot, NextExpander->tdDevice);
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscovering: Last Phy, remove expander%p start DownStream=%p\n",
NextExpander, NextExpander->tdDevice));
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, NextExpander);
tdsaSASDownStreamDiscovering(tiRoot, onePortContext, NextExpander->tdDevice);
}
break;
default:
TI_DBG3(("tdsaSASDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status));
}
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscovering: No more expander DONE\n"));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
}
return;
}
osGLOBAL void
tdsaCleanAllExp(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *ExpanderList;
tdsaExpander_t *tempExpander;
tdsaPortContext_t *tmpOnePortContext = onePortContext;
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: start\n"));
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: before all clean up\n"));
tdsaDumpAllFreeExp(tiRoot);
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: clean discoveringExpanderList\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (!TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
{
tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList);
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
TDLIST_DEQUEUE_THIS(&(tempExpander->linkNode));
TDLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(tdsaAllShared->freeExpanderList));
if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
break;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
}
ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
}
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: empty discoveringExpanderList\n"));
}
TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList));
TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: after all clean up\n"));
tdsaDumpAllFreeExp(tiRoot);
return;
}
osGLOBAL void
tdsaFreeAllExp(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *ExpanderList;
tdsaExpander_t *tempExpander;
tdsaPortContext_t *tmpOnePortContext = onePortContext;
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: start\n"));
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: before all clean up\n"));
tdsaDumpAllFreeExp(tiRoot);
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: clean discoveringExpanderList\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (!TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
{
tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList);
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
TDLIST_DEQUEUE_THIS(&(tempExpander->linkNode));
TDLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(tdsaAllShared->freeExpanderList));
if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
break;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
}
ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
}
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: empty discoveringExpanderList\n"));
}
TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList));
return;
}
osGLOBAL void
tdsaResetValidDeviceData(
agsaRoot_t *agRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdList_t *DeviceListList;
tdsaDeviceData_t *oneDeviceData;
TI_DBG3(("tdsaResetValidDeviceData: start\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdsaResetValidDeviceData: empty device list\n"));
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
oneDeviceData->valid = oneDeviceData->valid2;
oneDeviceData->valid2 = agFALSE;
DeviceListList = DeviceListList->flink;
TI_DBG3(("tdsaResetValidDeviceData: valid %d valid2 %d\n", oneDeviceData->valid, oneDeviceData->valid2));
}
}
return;
}
osGLOBAL void
tdssReportChanges(
agsaRoot_t *agRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
bit32 added = agFALSE, removed = agFALSE;
TI_DBG1(("tdssReportChanges: start\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdssReportChanges: empty device list\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG3(("tdssReportChanges: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdssReportChanges: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
if ( oneDeviceData->tdPortContext == onePortContext)
{
TI_DBG3(("tdssReportChanges: right portcontext\n"));
if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) )
{
TI_DBG3(("tdssReportChanges: same\n"));
oneDeviceData->valid = oneDeviceData->valid2;
oneDeviceData->valid2 = agFALSE;
}
else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) )
{
TI_DBG3(("tdssReportChanges: removed\n"));
removed = agTRUE;
oneDeviceData->valid = oneDeviceData->valid2;
oneDeviceData->valid2 = agFALSE;
oneDeviceData->satDevData.NumOfFCA = 0;
if ( (oneDeviceData->registered == agTRUE) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)
|| DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) )
)
{
tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
}
else if (oneDeviceData->registered == agTRUE)
{
TI_DBG1(("tdssReportChanges: calling saDeregisterDeviceHandle, did %d\n", oneDeviceData->id));
saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0);
}
oneDeviceData->registered = agFALSE;
#ifdef REMOVED
TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
#endif
}
else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) )
{
TI_DBG3(("tdssReportChanges: added\n"));
added = agTRUE;
oneDeviceData->valid = oneDeviceData->valid2;
oneDeviceData->valid2 = agFALSE;
}
else
{
TI_DBG6(("tdssReportChanges: else\n"));
}
}
else
{
TI_DBG1(("tdssReportChanges: different portcontext\n"));
}
DeviceListList = DeviceListList->flink;
}
if (added == agTRUE)
{
TI_DBG3(("tdssReportChanges: added at the end\n"));
#ifdef AGTIAPI_CTL
if (tdsaAllShared->SASConnectTimeLimit)
tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDeviceChange,
tiDeviceArrival);
else
#endif
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDeviceChange,
tiDeviceArrival,
agNULL
);
}
if (removed == agTRUE)
{
TI_DBG3(("tdssReportChanges: removed at the end\n"));
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDeviceChange,
tiDeviceRemoval,
agNULL
);
}
if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE)
{
TI_DBG1(("tdssReportChanges: missed chance to report. forced to report OK\n"));
onePortContext->discovery.forcedOK = agFALSE;
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscOK,
agNULL
);
}
if (added == agFALSE && removed == agFALSE)
{
TI_DBG3(("tdssReportChanges: the same\n"));
}
return;
}
osGLOBAL void
tdssReportRemovals(
agsaRoot_t *agRoot,
tdsaPortContext_t *onePortContext,
bit32 flag
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
bit32 removed = agFALSE;
agsaEventSource_t *eventSource;
bit32 PhyID;
bit32 HwAckSatus;
agsaDevHandle_t *agDevHandle = agNULL;
TI_DBG2(("tdssReportRemovals: start\n"));
PhyID = onePortContext->eventPhyID;
if (tdsaAllShared->eventSource[PhyID].EventValid == agTRUE &&
onePortContext->RegisteredDevNums == 0 &&
PhyID != 0xFF
)
{
TI_DBG2(("tdssReportRemovals: calling saHwEventAck\n"));
eventSource = &(tdsaAllShared->eventSource[PhyID].Source);
HwAckSatus = saHwEventAck(
agRoot,
agNULL,
0,
eventSource,
0,
0
);
if ( HwAckSatus != AGSA_RC_SUCCESS)
{
TI_DBG1(("tdssReportRemovals: failing in saHwEventAck; status %d\n", HwAckSatus));
}
tdsaAllShared->eventSource[PhyID].EventValid = agFALSE;
if (onePortContext->valid == agFALSE)
{
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData->tdPortContext == onePortContext)
{
osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
break;
}
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
DeviceListList = tdsaAllShared->MainDeviceList.flink;
}
else
{
DeviceListList = DeviceListList->flink;
}
}
tdsaPortContextReInit(tiRoot, onePortContext);
tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
TDLIST_DEQUEUE_THIS(&(onePortContext->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(tdsaAllShared->FreePortContextList));
tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
}
}
else
{
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdssReportRemovals: 1st empty device list\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData == agNULL)
{
TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n"));
return;
}
TI_DBG2(("tdssReportRemovals: 1st loop did %d\n", oneDeviceData->id));
TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG2(("tdssReportRemovals: valid %d\n", oneDeviceData->valid));
TI_DBG2(("tdssReportRemovals: valid2 %d\n", oneDeviceData->valid2));
TI_DBG2(("tdssReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached));
TI_DBG2(("tdssReportRemovals: registered %d\n", oneDeviceData->registered));
if ( oneDeviceData->tdPortContext == onePortContext && oneDeviceData->valid == agFALSE &&
oneDeviceData->valid2 == agFALSE && oneDeviceData->registered == agFALSE
)
{
TI_DBG2(("tdssReportRemovals: delete from MainLink\n"));
agDevHandle = oneDeviceData->agDevHandle;
tdsaDeviceDataReInit(tiRoot, oneDeviceData);
oneDeviceData->agDevHandle = agDevHandle;
oneDeviceData->tdPortContext = onePortContext;
osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
DeviceListList = tdsaAllShared->MainDeviceList.flink;
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
break;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
}
else
{
DeviceListList = DeviceListList->flink;
}
}
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdssReportRemovals: 2nd empty device list\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData == agNULL)
{
TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n"));
return;
}
TI_DBG2(("tdssReportRemovals: loop did %d\n", oneDeviceData->id));
TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG2(("tdssReportRemovals: valid %d\n", oneDeviceData->valid));
TI_DBG2(("tdssReportRemovals: valid2 %d\n", oneDeviceData->valid2));
TI_DBG2(("tdssReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached));
TI_DBG2(("tdssReportRemovals: registered %d\n", oneDeviceData->registered));
if ( oneDeviceData->tdPortContext == onePortContext)
{
TI_DBG2(("tdssReportRemovals: right portcontext pid %d\n", onePortContext->id));
if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE)
{
TI_DBG2(("tdssReportRemovals: removing\n"));
if ( DEVICE_IS_SSP_TARGET(oneDeviceData) ||
DEVICE_IS_STP_TARGET(oneDeviceData) ||
DEVICE_IS_SATA_DEVICE(oneDeviceData)
)
{
removed = agTRUE;
}
if ( (oneDeviceData->registered == agTRUE) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)
|| DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) )
)
{
TI_DBG2(("tdssReportRemovals: calling tdsaAbortAll\n"));
TI_DBG2(("tdssReportRemovals: did %d\n", oneDeviceData->id));
TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
}
else if (oneDeviceData->registered == agTRUE)
{
TI_DBG1(("tdssReportRemovals: calling saDeregisterDeviceHandle, did %d\n", oneDeviceData->id));
TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0);
}
oneDeviceData->valid = agFALSE;
oneDeviceData->valid2 = agFALSE;
oneDeviceData->registered = agFALSE;
oneDeviceData->satDevData.NumOfFCA = 0;
}
if (flag == agTRUE)
{
oneDeviceData->tdPortContext = agNULL;
TI_DBG1(("tdssReportRemovals: nulling-out tdPortContext; oneDeviceData did %d\n", oneDeviceData->id));
}
#ifdef REMOVED
if (oneDeviceData->DeviceType == TD_SATA_DEVICE &&
oneDeviceData->directlyAttached == agTRUE)
{
TI_DBG1(("tdssReportRemovals: device did %d\n", oneDeviceData->id));
TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceLis));
DeviceListList = tdsaAllShared->MainDeviceList.flink;
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
break;
}
}
else
{
DeviceListList = DeviceListList->flink;
}
#endif
DeviceListList = DeviceListList->flink;
}
else
{
if (oneDeviceData->tdPortContext != agNULL)
{
TI_DBG2(("tdssReportRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d oneDeviceData did %d\n",
oneDeviceData->tdPortContext->id, onePortContext->id, oneDeviceData->id));
}
else
{
TI_DBG1(("tdssReportRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d oneDeviceData did %d\n",
onePortContext->id, oneDeviceData->id));
}
DeviceListList = DeviceListList->flink;
}
}
if (removed == agTRUE)
{
TI_DBG2(("tdssReportRemovals: removed at the end\n"));
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDeviceChange,
tiDeviceRemoval,
agNULL
);
}
}
return;
}
osGLOBAL void
tdssInternalRemovals(
agsaRoot_t *agRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
TI_DBG2(("tdssInternalRemovals: start\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdssInternalRemovals: empty device list\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG3(("tdssInternalRemovals: loop did %d\n", oneDeviceData->id));
TI_DBG3(("tdssInternalRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdssInternalRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG3(("tdssInternalRemovals: valid %d\n", oneDeviceData->valid));
TI_DBG3(("tdssInternalRemovals: valid2 %d\n", oneDeviceData->valid2));
TI_DBG3(("tdssInternalRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached));
TI_DBG3(("tdssInternalRemovals: registered %d\n", oneDeviceData->registered));
if ( oneDeviceData->tdPortContext == onePortContext)
{
TI_DBG3(("tdssInternalRemovals: right portcontext pid %d\n", onePortContext->id));
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START)
{
TI_DBG3(("tdssInternalRemovals: incremental discovery\n"));
oneDeviceData->valid2 = agFALSE;
}
else
{
TI_DBG3(("tdssInternalRemovals: full discovery\n"));
oneDeviceData->valid = agFALSE;
}
DeviceListList = DeviceListList->flink;
}
else
{
if (oneDeviceData->tdPortContext != agNULL)
{
TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id));
}
else
{
TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id));
}
DeviceListList = DeviceListList->flink;
}
}
return;
}
osGLOBAL void
tdssDiscoveryErrorRemovals(
agsaRoot_t *agRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
TI_DBG1(("tdssDiscoveryErrorRemovals: start\n"));
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
TI_DBG1(("tdssDiscoveryErrorRemovals: empty device list\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG2(("tdssDiscoveryErrorRemovals: loop did %d\n", oneDeviceData->id));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG2(("tdssDiscoveryErrorRemovals: valid %d\n", oneDeviceData->valid));
TI_DBG2(("tdssDiscoveryErrorRemovals: valid2 %d\n", oneDeviceData->valid2));
TI_DBG2(("tdssDiscoveryErrorRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached));
TI_DBG2(("tdssDiscoveryErrorRemovals: registered %d\n", oneDeviceData->registered));
if ( oneDeviceData->tdPortContext == onePortContext)
{
TI_DBG2(("tdssDiscoveryErrorRemovals: right portcontext pid %d\n", onePortContext->id));
oneDeviceData->valid = agFALSE;
oneDeviceData->valid2 = agFALSE;
oneDeviceData->satDevData.NumOfFCA = 0;
if ( (oneDeviceData->registered == agTRUE) &&
( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)
|| DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) )
)
{
TI_DBG2(("tdssDiscoveryErrorRemovals: calling tdsaAbortAll\n"));
TI_DBG2(("tdssDiscoveryErrorRemovals: did %d\n", oneDeviceData->id));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
}
else if (oneDeviceData->registered == agTRUE)
{
TI_DBG2(("tdssDiscoveryErrorRemovals: calling saDeregisterDeviceHandle\n"));
TI_DBG2(("tdssDiscoveryErrorRemovals: did %d\n", oneDeviceData->id));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo));
saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0);
}
oneDeviceData->registered = agFALSE;
DeviceListList = DeviceListList->flink;
}
else
{
if (oneDeviceData->tdPortContext != agNULL)
{
TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id));
}
else
{
TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id));
}
DeviceListList = DeviceListList->flink;
}
}
return;
}
osGLOBAL void
tdsaSASDiscoverAbort(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
TI_DBG2(("tdsaSASDiscoverAbort: start\n"));
TI_DBG2(("tdsaSASDiscoverAbort: pPort=%p DONE\n", onePortContext));
TI_DBG2(("tdsaSASDiscoverAbort: DiscoveryState %d\n", onePortContext->DiscoveryState));
onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
tdsaCleanAllExp(tiRoot, onePortContext);
tdssReportRemovals(onePortContext->agRoot,
onePortContext,
agFALSE
);
}
#ifdef AGTIAPI_CTL
STATIC void
tdsaCTLNextDevice(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdIORequest_t *tdIORequest,
tdList_t *DeviceList);
STATIC void
tdsaCTLIOCompleted(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
bit32 agIOInfoLen,
void *agParam,
bit16 sspTag,
bit32 agOtherInfo)
{
tiRoot_t *tiRoot = (tiRoot_t*)
((tdsaRootOsData_t*)agRoot->osData)->tiRoot;
tdIORequestBody_t *tdIORequestBody;
tdIORequest_t *tdIORequest;
tdsaDeviceData_t *oneDeviceData;
tdIORequest = (tdIORequest_t *)agIORequest->osData;
tdIORequestBody = &tdIORequest->tdIORequestBody;
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
TI_DBG6(("tdsaCTLIOCompleted: stat x%x len %d id %d\n", agIOStatus,
agIOInfoLen, oneDeviceData->id));
if (agIOInfoLen)
{
TI_DBG6(("tdsaCTLIOCompleted: SASDevAddr 0x%x / 0x%x PhyId 0x%x WARN "
"setting CTL\n",
oneDeviceData->SASAddressID.sasAddressHi,
oneDeviceData->SASAddressID.sasAddressLo,
oneDeviceData->SASAddressID.phyIdentifier));
tdhexdump("tdsaCTLIOCompleted: response", (bit8 *)agParam, agIOInfoLen);
}
tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest,
oneDeviceData->MainLink.flink);
}
STATIC int
tdsaCTLModeSelect(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle,
tdIORequest_t *tdIORequest)
{
tiIORequest_t *tiIORequest;
tdsaDeviceData_t *oneDeviceData;
agsaRoot_t *agRoot = agNULL;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t*)tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t*)
&tdsaRoot->tdsaAllShared;
agsaIORequest_t *agIORequest = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
agsaSASRequestBody_t *agSASRequestBody = agNULL;
bit32 tiStatus;
bit32 saStatus;
tdIORequestBody_t *tdIORequestBody;
agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
unsigned char *virtAddr;
tiSgl_t agSgl;
static unsigned char cdb[6] =
{
MODE_SELECT,
PAGE_FORMAT,
0,
0,
DR_MODE_PG_SZ
};
virtAddr = (unsigned char*)tdIORequest->virtAddr;
virtAddr[0] = DR_MODE_PG_CODE;
virtAddr[1] = DR_MODE_PG_LENGTH;
virtAddr[8] = tdsaAllShared->SASConnectTimeLimit >> 8;
virtAddr[9] = tdsaAllShared->SASConnectTimeLimit & 0xff;
oneDeviceData = (tdsaDeviceData_t*)tiDeviceHandle->tdData;
TI_DBG4(("tdsaCTLModeSelect: id %d\n", oneDeviceData->id));
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tiIORequest = &tdIORequest->tiIORequest;
tdIORequestBody = &tdIORequest->tdIORequestBody;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength = DR_MODE_PG_SZ;
agIORequest = &tdIORequestBody->agIORequest;
agIORequest->sdkData = agNULL;
agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, cdb, 6);
agSSPInitiatorRequest->dataLength = DR_MODE_PG_SZ;
agSSPInitiatorRequest->firstBurstSize = 0;
tdIORequestBody->agRequestType = AGSA_SSP_INIT_WRITE;
tdIORequestBody->ioStarted = agTRUE;
tdIORequestBody->ioCompleted = agFALSE;
agSgl.lower = BIT32_TO_LEBIT32(tdIORequest->physLower32);
#if (BITS_PER_LONG > 32)
agSgl.upper = BIT32_TO_LEBIT32(tdIORequest->physUpper32);
#else
agSgl1.upper = 0;
#endif
agSgl.type = BIT32_TO_LEBIT32(tiSgl);
agSgl.len = BIT32_TO_LEBIT32(DR_MODE_PG_SZ);
tiStatus = itdssIOPrepareSGL(tiRoot, tdIORequestBody, &agSgl,
tdIORequest->virtAddr);
if (tiStatus != tiSuccess)
{
TI_DBG1(("tdsaCTLModeSelect: can't get SGL\n"));
ostiFreeMemory(tiRoot, tdIORequest->osMemHandle2, DR_MODE_PG_SZ);
ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest));
return tiError;
}
saStatus = saSSPStart(agRoot, agIORequest,
tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle,
AGSA_SSP_INIT_WRITE, agSASRequestBody, agNULL,
&tdsaCTLIOCompleted);
if (saStatus == AGSA_RC_SUCCESS)
{
tiStatus = tiSuccess;
TI_DBG4(("tdsaCTLModeSelect: saSSPStart OK\n"));
}
else
{
tdIORequestBody->ioStarted = agFALSE;
tdIORequestBody->ioCompleted = agTRUE;
if (saStatus == AGSA_RC_BUSY)
{
tiStatus = tiBusy;
TI_DBG4(("tdsaCTLModeSelect: saSSPStart busy\n"));
}
else
{
tiStatus = tiError;
TI_DBG4(("tdsaCTLModeSelect: saSSPStart Error\n"));
}
tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest,
oneDeviceData->MainLink.flink);
}
return tiStatus;
}
STATIC void
tdsaCTLNextDevice(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdIORequest_t *tdIORequest,
tdList_t *DeviceList)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *oneDeviceData;
tiIntrEventType_t eventType;
bit32 eventStatus;
int rc;
for (; DeviceList && DeviceList != &(tdsaAllShared->MainDeviceList);
DeviceList = DeviceList->flink)
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceList);
TI_DBG6(("tdsaCTLNextDevice: devHandle %p\n",
&(oneDeviceData->tiDeviceHandle)));
if (oneDeviceData->tdPortContext != onePortContext)
continue;
if ((oneDeviceData->discovered == agFALSE) &&
(oneDeviceData->registered == agTRUE) &&
DEVICE_IS_SSP_TARGET(oneDeviceData) &&
!DEVICE_IS_SSP_INITIATOR(oneDeviceData))
{
oneDeviceData->discovered = agTRUE;
rc = tdsaCTLModeSelect(tiRoot, &oneDeviceData->tiDeviceHandle,
tdIORequest);
TI_DBG1(("tdsaCTLNextDevice: ModeSelect ret %d\n", rc));
return;
}
}
TI_DBG2(("tdsaCTLNextDevice: no more devices found\n"));
eventType = tdIORequest->eventType;
eventStatus = tdIORequest->eventStatus;
ostiFreeMemory(tiRoot, tdIORequest->osMemHandle2, DR_MODE_PG_SZ);
ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest));
ostiInitiatorEvent(tiRoot, onePortContext->tiPortalContext, agNULL,
eventType, eventStatus, agNULL);
}
osGLOBAL void
tdsaCTLSet(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tiIntrEventType_t eventType,
bit32 eventStatus)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequest_t *tdIORequest;
tdIORequestBody_t *tdIORequestBody;
tiIORequest_t *tiIORequest;
bit32 memAllocStatus;
void *osMemHandle;
bit32 physUpper32;
bit32 physLower32;
TI_DBG2(("tdsaCTLSet: tiPortalContext pid %d etyp %x stat %x\n",
onePortContext->id, eventType, eventStatus));
if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
{
TI_DBG1(("tdsaCTLSet: discovery not completed\n"));
return;
}
memAllocStatus = ostiAllocMemory(tiRoot, &osMemHandle, (void **)&tdIORequest,
&physUpper32, &physLower32, 8,
sizeof(*tdIORequest), agTRUE);
if (memAllocStatus != tiSuccess || tdIORequest == agNULL)
{
TI_DBG1(("tdsaCTLSet: ostiAllocMemory failed\n"));
return;
}
osti_memset(tdIORequest, 0, sizeof(*tdIORequest));
tdIORequest->osMemHandle = osMemHandle;
tdIORequest->eventType = eventType;
tdIORequest->eventStatus = eventStatus;
tiIORequest = &tdIORequest->tiIORequest;
tdIORequestBody = &tdIORequest->tdIORequestBody;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->IOCompletionFunc = NULL;
tdIORequestBody->tiIORequest = tiIORequest;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength = 16;
tdIORequestBody->agIORequest.osData = (void *)tdIORequest;
memAllocStatus = ostiAllocMemory(tiRoot, &tdIORequest->osMemHandle2,
(void **)&tdIORequest->virtAddr,
&tdIORequest->physUpper32,
&tdIORequest->physLower32,
8, DR_MODE_PG_SZ, agFALSE);
if (memAllocStatus != tiSuccess || tdIORequest == agNULL)
{
TI_DBG1(("tdsaCTLSet: ostiAllocMemory noncached failed\n"));
ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest));
return;
}
osti_memset(tdIORequest->virtAddr, 0, DR_MODE_PG_SZ);
tdsaCTLNextDevice(tiRoot, onePortContext, tdIORequest,
tdsaAllShared->MainDeviceList.flink);
}
#endif
osGLOBAL void
tdsaSASDiscoverDone(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
bit32 flag
)
{
#ifndef SATA_ENABLE
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
#endif
TI_DBG3(("tdsaSASDiscoverDone: start\n"));
TI_DBG3(("tdsaSASDiscoverDone: pPort=%p DONE\n", onePortContext));
TI_DBG3(("tdsaSASDiscoverDone: pid %d\n", onePortContext->id));
onePortContext->discovery.status = DISCOVERY_SAS_DONE;
#ifdef TD_INTERNAL_DEBUG
TI_DBG3(("tdsaSASDiscoverDone: BEFORE\n"));
tdsaDumpAllExp(tiRoot, onePortContext, agNULL);
tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL);
#endif
tdsaCleanAllExp(tiRoot, onePortContext);
#ifdef TD_INTERNAL_DEBUG
TI_DBG3(("tdsaSASDiscoverDone: AFTER\n"));
tdsaDumpAllExp(tiRoot, onePortContext, agNULL);
tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL);
#endif
#ifndef SATA_ENABLE
if (onePortContext->discovery.SeenBC == agTRUE)
{
TI_DBG3(("tdsaSASDiscoverDone: broadcast change; discover again\n"));
tdssInternalRemovals(onePortContext->agRoot,
onePortContext
);
onePortContext->discovery.SeenBC = agFALSE;
if (tdsaAllShared->ResetInDiscovery != 0 &&
onePortContext->discovery.ResetTriggerred == agTRUE)
{
TI_DBG2(("tdsaSASDiscoverDone: tdsaBCTimer\n"));
tdsaBCTimer(tiRoot, onePortContext);
}
else
{
tdsaDiscover(
tiRoot,
onePortContext,
TDSA_DISCOVERY_TYPE_SAS,
TDSA_DISCOVERY_OPTION_INCREMENTAL_START
);
}
}
else
{
onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
if (flag == tiSuccess)
{
#ifdef AGTIAPI_CTL
if (tdsaAllShared->SASConnectTimeLimit)
tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery,
tiDiscOK);
else
#endif
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscOK,
agNULL
);
}
else
{
TI_DBG1(("tdsaSASDiscoverDone: discovery failed\n"));
tdssDiscoveryErrorRemovals(onePortContext->agRoot,
onePortContext
);
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscFailed,
agNULL
);
}
}
else
{
if (flag == tiSuccess)
{
tdssReportChanges(onePortContext->agRoot,
onePortContext
);
}
else
{
tdssReportRemovals(onePortContext->agRoot,
onePortContext,
agFALSE
);
}
}
}
#ifdef TBD
tdsaAckBC(tiRoot, onePortContext);
#endif
#endif
#ifdef SATA_ENABLE
if (flag == tiSuccess)
{
TI_DBG3(("tdsaSASDiscoverDone: calling SATA discovery\n"));
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
TI_DBG3(("tdsaSASDiscoverDone: calling FULL SATA discovery\n"));
tdsaDiscover(
tiRoot,
onePortContext,
AG_SA_DISCOVERY_TYPE_SATA,
TDSA_DISCOVERY_OPTION_FULL_START
);
}
else
{
TI_DBG3(("tdsaSASDiscoverDone: calling INCREMENTAL SATA discovery\n"));
tdsaDiscover(
tiRoot,
onePortContext,
AG_SA_DISCOVERY_TYPE_SATA,
TDSA_DISCOVERY_OPTION_INCREMENTAL_START
);
}
}
else
{
TI_DBG1(("tdsaSASDiscoverDone: Error; clean up\n"));
tdssDiscoveryErrorRemovals(onePortContext->agRoot,
onePortContext
);
onePortContext->discovery.SeenBC = agFALSE;
onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscFailed,
agNULL
);
}
#endif
return;
}
osGLOBAL void
tdsaReportManInfoSend(
tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData
)
{
agsaRoot_t *agRoot;
agRoot = oneDeviceData->agRoot;
TI_DBG2(("tdsaReportManInfoSend: start\n"));
tdSMPStart(
tiRoot,
agRoot,
oneDeviceData,
SMP_REPORT_MANUFACTURE_INFORMATION,
agNULL,
0,
AGSA_SMP_INIT_REQ,
agNULL,
0
);
return;
}
osGLOBAL void
tdsaReportManInfoRespRcvd(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
tdsaDeviceData_t *oneDeviceData,
tdssSMPFrameHeader_t *frameHeader,
agsaFrameHandle_t frameHandle
)
{
tdsaPortContext_t *onePortContext;
tdsaDiscovery_t *discovery;
TI_DBG2(("tdsaReportManInfoRespRcvd: start\n"));
TI_DBG2(("tdsaReportManInfoRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG2(("tdsaReportManInfoRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
onePortContext = oneDeviceData->tdPortContext;
discovery = &(onePortContext->discovery);
if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
{
TI_DBG2(("tdsaReportManInfoRespRcvd: SMP accepted\n"));
}
else
{
TI_DBG1(("tdsaReportManInfoRespRcvd: SMP NOT accepted; fn result 0x%x\n", frameHeader->smpFunctionResult));
}
TI_DBG2(("tdsaReportManInfoRespRcvd: discovery retries %d\n", discovery->retries));
discovery->retries++;
if (discovery->retries >= DISCOVERY_RETRIES)
{
TI_DBG1(("tdsaReportManInfoRespRcvd: retries are over\n"));
discovery->retries = 0;
}
else
{
TI_DBG1(("tdsaReportManInfoRespRcvd: keep retrying\n"));
tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData);
}
return;
}
osGLOBAL void
tdsaReportGeneralSend(
tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData
)
{
agsaRoot_t *agRoot;
agRoot = oneDeviceData->agRoot;
TI_DBG3(("tdsaReportGeneralSend: start\n"));
tdSMPStart(
tiRoot,
agRoot,
oneDeviceData,
SMP_REPORT_GENERAL,
agNULL,
0,
AGSA_SMP_INIT_REQ,
agNULL,
0
);
return;
}
osGLOBAL void
tdsaReportGeneralRespRcvd(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
tdsaDeviceData_t *oneDeviceData,
tdssSMPFrameHeader_t *frameHeader,
agsaFrameHandle_t frameHandle
)
{
smpRespReportGeneral_t tdSMPReportGeneralResp;
smpRespReportGeneral_t *ptdSMPReportGeneralResp;
tdsaExpander_t *oneExpander;
tdsaPortContext_t *onePortContext;
tdsaDiscovery_t *discovery;
#ifdef REMOVED
bit32 i;
#endif
#ifndef DIRECT_SMP
tdssSMPRequestBody_t *tdSMPRequestBody;
tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
#endif
TI_DBG3(("tdsaReportGeneralRespRcvd: start\n"));
TI_DBG3(("tdsaReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
ptdSMPReportGeneralResp = &tdSMPReportGeneralResp;
osti_memset(&tdSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t));
#ifdef DIRECT_SMP
saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
#else
saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
#endif
#ifndef DIRECT_SMP
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPReqosMemHandle,
tdSMPRequestBody->IndirectSMPReqLen
);
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPResposMemHandle,
tdSMPRequestBody->IndirectSMPRespLen
);
#endif
onePortContext = oneDeviceData->tdPortContext;
discovery = &(onePortContext->discovery);
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaReportGeneralRespRcvd: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
{
oneDeviceData->numOfPhys = (bit8) ptdSMPReportGeneralResp->numOfPhys;
oneExpander = oneDeviceData->tdExpander;
oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(ptdSMPReportGeneralResp);
#ifdef REMOVED
for ( i = 0; i < oneDeviceData->numOfPhys; i++ )
{
oneExpander->currentIndex[i] = 0;
}
#endif
oneExpander->configReserved = 0;
oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(ptdSMPReportGeneralResp) ? 1 : 0;
oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(ptdSMPReportGeneralResp) ? 1 : 0;
TI_DBG3(("tdsaReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
TI_DBG3(("tdsaReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n",
oneExpander->configRouteTable, oneExpander->configuring));
if (oneExpander->configuring == 1)
{
discovery->retries++;
if (discovery->retries >= DISCOVERY_RETRIES)
{
TI_DBG1(("tdsaReportGeneralRespRcvd: retries are over\n"));
discovery->retries = 0;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else
{
TI_DBG1(("tdsaReportGeneralRespRcvd: keep retrying\n"));
tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
discovery->retries = 0;
tdsaDiscoverSend(tiRoot, oneDeviceData);
}
}
else
{
TI_DBG1(("tdsaReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery\n", frameHeader->smpFunctionResult));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
return;
}
osGLOBAL void
tdsaDiscoverSend(
tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData
)
{
agsaRoot_t *agRoot;
tdsaExpander_t *oneExpander;
smpReqDiscover_t smpDiscoverReq;
TI_DBG3(("tdsaDiscoverSend: start\n"));
TI_DBG3(("tdsaDiscoverSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
agRoot = oneDeviceData->agRoot;
oneExpander = oneDeviceData->tdExpander;
TI_DBG3(("tdsaDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId));
osti_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t));
smpDiscoverReq.reserved1 = 0;
smpDiscoverReq.reserved2 = 0;
smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId;
smpDiscoverReq.reserved3 = 0;
tdSMPStart(
tiRoot,
agRoot,
oneDeviceData,
SMP_DISCOVER,
(bit8 *)&smpDiscoverReq,
sizeof(smpReqDiscover_t),
AGSA_SMP_INIT_REQ,
agNULL,
0
);
return;
}
osGLOBAL void
tdsaDiscoverRespRcvd(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
tdsaDeviceData_t *oneDeviceData,
tdssSMPFrameHeader_t *frameHeader,
agsaFrameHandle_t frameHandle
)
{
smpRespDiscover_t *ptdSMPDiscoverResp;
tdsaPortContext_t *onePortContext;
tdsaExpander_t *oneExpander;
tdsaDiscovery_t *discovery;
#ifndef DIRECT_SMP
tdssSMPRequestBody_t *tdSMPRequestBody;
#endif
TI_DBG3(("tdsaDiscoverRespRcvd: start\n"));
TI_DBG3(("tdsaDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
onePortContext = oneDeviceData->tdPortContext;
oneExpander = oneDeviceData->tdExpander;
discovery = &(onePortContext->discovery);
#ifndef DIRECT_SMP
tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
#endif
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaDiscoverRespRcvd: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
ptdSMPDiscoverResp = &(discovery->SMPDiscoverResp);
#ifdef DIRECT_SMP
saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
#else
saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
#endif
#ifndef DIRECT_SMP
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPReqosMemHandle,
tdSMPRequestBody->IndirectSMPReqLen
);
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPResposMemHandle,
tdSMPRequestBody->IndirectSMPRespLen
);
#endif
if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
{
if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
{
tdsaSASUpStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
}
else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
{
tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
}
else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
{
TI_DBG2(("tdsaDiscoverRespRcvd: still configuring routing; setting timer\n"));
TI_DBG2(("tdsaDiscoverRespRcvd: onePortContext %p oneDeviceData %p ptdSMPDiscoverResp %p\n", onePortContext, oneDeviceData, ptdSMPDiscoverResp));
tdhexdump("tdsaDiscoverRespRcvd", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
}
else
{
}
}
else if (frameHeader->smpFunctionResult == PHY_VACANT)
{
TI_DBG3(("tdsaDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n",
oneExpander->discoveringPhyId));
if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
{
tdsaSASUpStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander);
}
else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
{
tdsaSASDownStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander);
}
else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
{
TI_DBG1(("tdsaDiscoverRespRcvd: still configuring routing; setting timer\n"));
TI_DBG1(("tdsaDiscoverRespRcvd: onePortContext %p oneDeviceData %p ptdSMPDiscoverResp %p\n", onePortContext, oneDeviceData, ptdSMPDiscoverResp));
tdhexdump("tdsaDiscoverRespRcvd", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
}
}
else
{
TI_DBG1(("tdsaDiscoverRespRcvd: Discovery Error SMP function return result error=%x\n",
frameHeader->smpFunctionResult));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
return;
}
osGLOBAL void
tdsaSASUpStreamDiscoverExpanderPhy(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander,
smpRespDiscover_t *pDiscoverResp
)
{
tdsaDeviceData_t *oneDeviceData;
tdsaDeviceData_t *AttachedDevice = agNULL;
tdsaExpander_t *AttachedExpander;
agsaSASIdentify_t sasIdentify;
bit8 connectionRate;
bit32 attachedSasHi, attachedSasLo;
tdsaSASSubID_t agSASSubID;
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
oneDeviceData = oneExpander->tdDevice;
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n",
oneExpander->discoveringPhyId,
oneDeviceData->SASAddressID.sasAddressHi,
oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG3((" Attached device: %s\n",
( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" :
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" :
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander")))));
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
{
TI_DBG3((" SAS address : %08x-%08x\n",
DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp),
DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp)));
TI_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0));
TI_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier));
TI_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier));
}
if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier)
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n"));
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier));
tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
return;
}
oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp);
if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE )
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n"));
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
return;
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n"));
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
{
sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier;
sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70);
sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator;
sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target;
*(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi;
*(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo;
agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify);
agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify);
agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp;
agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp;
attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp);
attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp);
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n"));
tdsaSASExpanderUpStreamPhyAdd(tiRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier);
if (oneExpander->hasUpStreamDevice == agTRUE)
{
if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) ||
(oneExpander->upStreamSASAddressLo != attachedSasLo)) &&
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE ||
DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
)
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
else
{
oneExpander->hasUpStreamDevice = agTRUE;
oneExpander->upStreamSASAddressHi = attachedSasHi;
oneExpander->upStreamSASAddressLo = attachedSasLo;
if ( (onePortContext->sasLocalAddressHi != attachedSasHi)
|| (onePortContext->sasLocalAddressLo != attachedSasLo) )
{
AttachedDevice = tdsaPortSASDeviceFind(tiRoot, onePortContext, attachedSasLo, attachedSasHi);
if ( AttachedDevice != agNULL)
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Seen This Device Before\n"));
if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE)
{
AttachedExpander = AttachedDevice->tdExpander;
if ( (AttachedExpander->upStreamSASAddressHi ==
DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo))
&& (AttachedExpander->upStreamSASAddressLo ==
DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) )
{
oneExpander->tdUpStreamExpander = AttachedExpander;
}
else
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error loop detection\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!\n"));
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: New device\n"));
connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)));
TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate));
TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp)));
TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate));
if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
{
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
STP_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
else
{
AttachedDevice = tdsaFindRegNValid(
onePortContext->agRoot,
onePortContext,
&agSASSubID
);
if (AttachedDevice == agNULL)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
STP_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
}
}
else
{
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
else
{
AttachedDevice = tdsaFindRegNValid(
onePortContext->agRoot,
onePortContext,
&agSASSubID
);
if (AttachedDevice == agNULL)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
}
}
if ( AttachedDevice != agNULL)
{
if ( DISCRSP_IS_SSP_TARGET(pDiscoverResp)
|| DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)
|| DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)
|| DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) )
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n",
attachedSasHi, attachedSasLo));
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n"));
}
if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE)
|| (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) )
{
AttachedExpander = tdssSASDiscoveringExpanderAlloc(
tiRoot,
onePortContext,
AttachedDevice
);
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander));
if ( AttachedExpander != agNULL)
{
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander);
oneExpander->tdUpStreamExpander = AttachedExpander;
}
else
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n"));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found end device\n"));
AttachedDevice->tdExpander = oneExpander;
oneExpander->tdUpStreamExpander = agNULL;
}
}
else
{
TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to add a device\n"));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
}
}
}
}
}
oneExpander->discoveringPhyId ++;
if (onePortContext->discovery.status == DISCOVERY_UP_STREAM)
{
if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n"));
tdsaDiscoverSend(tiRoot, oneDeviceData);
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n"));
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status));
}
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
return;
}
osGLOBAL tdsaExpander_t *
tdsaFindUpStreamConfigurableExp(tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander)
{
tdsaExpander_t *ret=agNULL;
tdsaExpander_t *UpsreamExpander = oneExpander->tdUpStreamExpander;
TI_DBG3(("tdsaFindUpStreamConfigurableExp: start\n"));
TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
if (UpsreamExpander)
{
TI_DBG3(("tdsaFindUpStreamConfigurableExp: NO upsream expander\n"));
}
else
{
while (UpsreamExpander)
{
TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrHi 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrLo 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressLo));
UpsreamExpander = UpsreamExpander->tdUpStreamExpander;
}
}
return ret;
}
osGLOBAL void
tdsaSASUpStreamDiscoverExpanderPhySkip(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander
)
{
tdsaDeviceData_t *oneDeviceData;
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: start\n"));
oneDeviceData = oneExpander->tdDevice;
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
oneExpander->discoveringPhyId ++;
if (onePortContext->discovery.status == DISCOVERY_UP_STREAM)
{
if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: More Phys to discover\n"));
tdsaDiscoverSend(tiRoot, oneDeviceData);
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: No More Phys\n"));
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status));
}
TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
return;
}
osGLOBAL tdsaExpander_t *
tdsaFindDownStreamConfigurableExp(tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander)
{
tdsaExpander_t *ret=agNULL;
tdsaExpander_t *DownsreamExpander = oneExpander->tdCurrentDownStreamExpander;
TI_DBG3(("tdsaFindDownStreamConfigurableExp: start\n"));
TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
if (DownsreamExpander)
{
TI_DBG3(("tdsaFindDownStreamConfigurableExp: NO downsream expander\n"));
}
else
{
while (DownsreamExpander)
{
TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrHi 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrLo 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressLo));
DownsreamExpander = DownsreamExpander->tdCurrentDownStreamExpander;
}
}
return ret;
}
osGLOBAL void
dumpRoutingAttributes(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander,
bit8 phyID
)
{
bit32 i;
TI_DBG3(("dumpRoutingAttributes: start\n"));
TI_DBG3(("dumpRoutingAttributes: phyID %d\n", phyID));
TI_DBG3(("dumpRoutingAttributes: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("dumpRoutingAttributes: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
for(i=0;i <= ((bit32)phyID + 1); i++)
{
TI_DBG3(("dumpRoutingAttributes: index %d routing attribute %d\n", i, oneExpander->routingAttribute[i]));
}
return;
}
osGLOBAL void
tdsaDumpAllExp(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander
)
{
#if 0
tdList_t *ExpanderList;
tdsaExpander_t *tempExpander;
tdsaExpander_t *UpsreamExpander;
tdsaExpander_t *DownsreamExpander;
tdsaPortContext_t *tmpOnePortContext = onePortContext;
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: start\n"));
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: onePortcontext %p oneExpander %p\n", onePortContext, oneExpander));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: empty discoveringExpanderList\n"));
return;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
}
ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
{
tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList);
UpsreamExpander = tempExpander->tdUpStreamExpander;
DownsreamExpander = tempExpander->tdCurrentDownStreamExpander;
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: expander id %d\n", tempExpander->id));
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo));
if (UpsreamExpander)
{
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Up exp addrHi 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Up exp addrLo 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressLo));
}
else
{
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Upstream expander\n"));
}
if (DownsreamExpander)
{
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Down exp addrHi 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Down exp addrLo 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressLo));
}
else
{
TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Downstream expander\n"));
}
ExpanderList = ExpanderList->flink;
}
#endif
return;
}
osGLOBAL void
tdsaDumpAllUpExp(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander
)
{
return;
}
osGLOBAL void
tdsaDumpAllFreeExp(
tiRoot_t *tiRoot
)
{
return;
}
osGLOBAL bit32
tdsaDuplicateConfigSASAddr(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander,
bit32 configSASAddressHi,
bit32 configSASAddressLo
)
{
bit32 i;
bit32 ret = agFALSE;
TI_DBG3(("tdsaDuplicateConfigSASAddr: start\n"));
if (oneExpander == agNULL)
{
TI_DBG3(("tdsaDuplicateConfigSASAddr: NULL expander\n"));
return agTRUE;
}
if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo
)
{
TI_DBG3(("tdsaDuplicateConfigSASAddr: unnecessary\n"));
return agTRUE;
}
TI_DBG3(("tdsaDuplicateConfigSASAddr: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaDuplicateConfigSASAddr: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaDuplicateConfigSASAddr: configsasAddressHi 0x%08x\n", configSASAddressHi));
TI_DBG3(("tdsaDuplicateConfigSASAddr: configsasAddressLo 0x%08x\n", configSASAddressLo));
TI_DBG3(("tdsaDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex));
for(i=0;i<oneExpander->configSASAddrTableIndex;i++)
{
if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi &&
oneExpander->configSASAddressLoTable[i] == configSASAddressLo
)
{
TI_DBG3(("tdsaDuplicateConfigSASAddr: FOUND!!!\n"));
ret = agTRUE;
break;
}
}
if (ret == agFALSE)
{
TI_DBG3(("tdsaDuplicateConfigSASAddr: adding configSAS Addr!!!\n"));
TI_DBG3(("tdsaDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex));
oneExpander->configSASAddressHiTable[oneExpander->configSASAddrTableIndex] = configSASAddressHi;
oneExpander->configSASAddressLoTable[oneExpander->configSASAddrTableIndex] = configSASAddressLo;
oneExpander->configSASAddrTableIndex++;
}
return ret;
}
osGLOBAL tdsaExpander_t *
tdsaFindConfigurableExp(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander
)
{
tdsaExpander_t *tempExpander;
tdsaPortContext_t *tmpOnePortContext = onePortContext;
tdsaExpander_t *ret = agNULL;
TI_DBG3(("tdsaFindConfigurableExp: start\n"));
if (oneExpander == agNULL)
{
TI_DBG3(("tdsaFindConfigurableExp: NULL expander\n"));
return agNULL;
}
TI_DBG3(("tdsaFindConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
TI_DBG3(("tdsaFindConfigurableExp: empty UpdiscoveringExpanderList\n"));
return agNULL;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
}
tempExpander = oneExpander->tdUpStreamExpander;
while (tempExpander)
{
TI_DBG3(("tdsaFindConfigurableExp: loop exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindConfigurableExp: loop exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo));
if (tempExpander->configRouteTable)
{
TI_DBG3(("tdsaFindConfigurableExp: found configurable expander\n"));
ret = tempExpander;
break;
}
tempExpander = tempExpander->tdUpStreamExpander;
}
return ret;
}
osGLOBAL void
tdsaSASDownStreamDiscoverExpanderPhy(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander,
smpRespDiscover_t *pDiscoverResp
)
{
tdsaDeviceData_t *oneDeviceData;
tdsaExpander_t *UpStreamExpander;
tdsaDeviceData_t *AttachedDevice = agNULL;
tdsaExpander_t *AttachedExpander;
agsaSASIdentify_t sasIdentify;
bit8 connectionRate;
bit32 attachedSasHi, attachedSasLo;
tdsaSASSubID_t agSASSubID;
tdsaExpander_t *ConfigurableExpander = agNULL;
bit32 dupConfigSASAddr = agFALSE;
bit32 configSASAddressHi;
bit32 configSASAddressLo;
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: start\n"));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TD_ASSERT(tiRoot, "(tdsaSASDownStreamDiscoverExpanderPhy) agRoot NULL");
TD_ASSERT(onePortContext, "(tdsaSASDownStreamDiscoverExpanderPhy) pPort NULL");
TD_ASSERT(oneExpander, "(tdsaSASDownStreamDiscoverExpanderPhy) pExpander NULL");
TD_ASSERT(pDiscoverResp, "(tdsaSASDownStreamDiscoverExpanderPhy) pDiscoverResp NULL");
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->tdDevice));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
#ifdef TD_INTERNAL_DEBUG
tdsaDumpAllExp(tiRoot, onePortContext, oneExpander);
tdsaFindUpStreamConfigurableExp(tiRoot, oneExpander);
tdsaFindDownStreamConfigurableExp(tiRoot, oneExpander);
#endif
oneDeviceData = oneExpander->tdDevice;
TD_ASSERT(oneDeviceData, "(tdsaSASDownStreamDiscoverExpanderPhy) pDevice NULL");
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n",
oneExpander->discoveringPhyId,
oneDeviceData->SASAddressID.sasAddressHi,
oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG3((" Attached device: %s\n",
( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" :
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" :
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander")))));
if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n"));
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier));
tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
return;
}
#ifdef TD_INTERNAL_DEBUG
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_NO_DEVICE)
{
tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t));
}
#endif
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
{
TI_DBG3((" SAS address : %08x-%08x\n",
DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp),
DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp)));
TI_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0));
TI_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0));
TI_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0));
TI_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier));
TI_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier));
}
oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp);
oneExpander->discoverSMPAllowed = agTRUE;
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
{
sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier;
sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70);
sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator;
sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target;
*(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi;
*(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo;
agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify);
agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify);
agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp;
agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp;
attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp);
attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp);
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT)
{
if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
|| (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) )
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error direct routing can't connect to expander\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
return;
}
}
if ( (attachedSasHi != onePortContext->sasLocalAddressHi)
|| (attachedSasLo != onePortContext->sasLocalAddressLo) )
{
AttachedDevice = tdsaPortSASDeviceFind(tiRoot, onePortContext, attachedSasLo, attachedSasHi);
if ( AttachedDevice == agNULL)
{
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE &&
(DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE ||
DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else
{
connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo)));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp)));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate));
if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
{
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
STP_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
else
{
AttachedDevice = tdsaFindRegNValid(
onePortContext->agRoot,
onePortContext,
&agSASSubID
);
if (AttachedDevice == agNULL)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
STP_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
}
}
else
{
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
else
{
AttachedDevice = tdsaFindRegNValid(
onePortContext->agRoot,
onePortContext,
&agSASSubID
);
if (AttachedDevice == agNULL)
{
AttachedDevice = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
}
}
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice));
if ( AttachedDevice != agNULL)
{
if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify)
|| SA_IDFRM_IS_SMP_TARGET(&sasIdentify)
|| SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify)
|| SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) )
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n"));
}
else
{
if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) ||
SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) )
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n"));
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Other type of device.\n"));
}
}
AttachedDevice->tdExpander = oneExpander;
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE)
{
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys are connected\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE)
{
AttachedExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, AttachedDevice);
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander));
if ( AttachedExpander != agNULL)
{
if (oneExpander->configRouteTable)
{
tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId);
}
tdsaSASExpanderUpStreamPhyAdd(tiRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId);
AttachedExpander->hasUpStreamDevice = agTRUE;
AttachedExpander->upStreamSASAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
AttachedExpander->upStreamSASAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
AttachedExpander->tdUpStreamExpander = oneExpander;
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander);
}
else
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n"));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
}
if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before\n"));
tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander);
UpStreamExpander = oneExpander->tdUpStreamExpander;
ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo);
configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo);
if (ConfigurableExpander)
{
if ( (ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi
== DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) &&
(ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo
== DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo))
)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before loc 1\n"));
configSASAddressHi = oneExpander->tdDevice->SASAddressID.sasAddressHi;
configSASAddressLo = oneExpander->tdDevice->SASAddressID.sasAddressLo;
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before loc 2\n"));
configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo);
configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo);
}
}
dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
ConfigurableExpander,
configSASAddressHi,
configSASAddressLo
);
if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st q123\n"));
UpStreamExpander->tdCurrentDownStreamExpander = oneExpander;
ConfigurableExpander->currentDownStreamPhyIndex =
tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander);
ConfigurableExpander->tdReturnginExpander = oneExpander;
tdsaSASRoutingEntryAdd(tiRoot,
ConfigurableExpander,
ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
configSASAddressHi,
configSASAddressLo
);
}
}
}
else
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to add a device\n"));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
}
else
{
if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
{
if ( oneExpander->hasUpStreamDevice == agFALSE)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error loop, or end device connects to two expanders\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else
{
if ( (oneExpander->upStreamSASAddressHi != attachedSasHi)
|| (oneExpander->upStreamSASAddressLo != attachedSasLo) )
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two subtractive phys\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
}
else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE)
{
if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error fan out expander to routing table phy\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE)
{
AttachedExpander = AttachedDevice->tdExpander;
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander));
if ( AttachedExpander->hasUpStreamDevice == agTRUE)
{
if ( (AttachedExpander->upStreamSASAddressHi
!= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo))
|| (AttachedExpander->upStreamSASAddressLo
!= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)))
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (1)\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander));
if (oneExpander->configRouteTable)
{
tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId);
}
tdsaSASExpanderUpStreamPhyAdd(tiRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId);
tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander);
}
}
else
{
TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (2)\n"));
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo
= DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi
= DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo);
onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
}
}
if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before\n"));
tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander);
UpStreamExpander = oneExpander->tdUpStreamExpander;
ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo);
configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo);
if (ConfigurableExpander)
{
if ( (ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi
== DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) &&
(ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo
== DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo))
)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before loc 1\n"));
configSASAddressHi = oneExpander->tdDevice->SASAddressID.sasAddressHi;
configSASAddressLo = oneExpander->tdDevice->SASAddressID.sasAddressLo;
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before loc 2\n"));
configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo);
configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo);
}
}
dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
ConfigurableExpander,
configSASAddressHi,
configSASAddressLo
);
if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd q123 \n"));
UpStreamExpander->tdCurrentDownStreamExpander = oneExpander;
ConfigurableExpander->currentDownStreamPhyIndex =
tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander);
ConfigurableExpander->tdReturnginExpander = oneExpander;
tdsaSASRoutingEntryAdd(tiRoot,
ConfigurableExpander,
ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
configSASAddressHi,
configSASAddressLo
);
}
}
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START)
{
connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)));
if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SATA_STP\n"));
tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
STP_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SAS\n"));
tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
sasIdentify,
agFALSE,
connectionRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
oneDeviceData,
pDiscoverResp->phyIdentifier
);
}
}
}
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Self\n"));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 3rd before\n"));
tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander);
UpStreamExpander = oneExpander->tdUpStreamExpander;
ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
ConfigurableExpander,
onePortContext->sasLocalAddressHi,
onePortContext->sasLocalAddressLo
);
if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 3rd q123 Setup routing table\n"));
UpStreamExpander->tdCurrentDownStreamExpander = oneExpander;
ConfigurableExpander->currentDownStreamPhyIndex =
tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander);
ConfigurableExpander->tdReturnginExpander = oneExpander;
tdsaSASRoutingEntryAdd(tiRoot,
ConfigurableExpander,
ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
onePortContext->sasLocalAddressHi,
onePortContext->sasLocalAddressLo
);
}
}
}
else
{
}
oneExpander->discoveringPhyId ++;
if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM )
{
if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: More Phys to discover\n"));
tdsaDiscoverSend(tiRoot, oneDeviceData);
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: No More Phys\n"));
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status));
}
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
return;
}
osGLOBAL void
tdsaSASDownStreamDiscoverExpanderPhySkip(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander
)
{
tdsaDeviceData_t *oneDeviceData;
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: start\n"));
oneDeviceData = oneExpander->tdDevice;
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
oneExpander->discoveringPhyId ++;
if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM )
{
if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: More Phys to discover\n"));
tdsaDiscoverSend(tiRoot, oneDeviceData);
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: No More Phys\n"));
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status));
}
TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
return;
}
osGLOBAL bit32
tdsaSASRoutingEntryAdd(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander,
bit32 phyId,
bit32 configSASAddressHi,
bit32 configSASAddressLo
)
{
bit32 ret = agTRUE;
smpReqConfigureRouteInformation_t confRoutingInfo;
tdsaPortContext_t *onePortContext;
bit32 i;
agsaRoot_t *agRoot;
TI_DBG3(("tdsaSASRoutingEntryAdd: start\n"));
TI_DBG3(("tdsaSASRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaSASRoutingEntryAdd: phyid %d\n", phyId));
if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo
)
{
TI_DBG3(("tdsaSASRoutingEntryAdd: unnecessary\n"));
return ret;
}
if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE)
{
TI_DBG3(("tdsaSASRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId]));
return ret;
}
agRoot = oneExpander->tdDevice->agRoot;
onePortContext = oneExpander->tdDevice->tdPortContext;
onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING;
osti_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t));
if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex )
{
TI_DBG3(("tdsaSASRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi));
TI_DBG3(("tdsaSASRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo));
TI_DBG3(("tdsaSASRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId]));
oneExpander->configSASAddressHi = configSASAddressHi;
oneExpander->configSASAddressLo = configSASAddressLo;
confRoutingInfo.reserved1[0] = 0;
confRoutingInfo.reserved1[1] = 0;
OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId]));
confRoutingInfo.reserved2 = 0;
confRoutingInfo.phyIdentifier = (bit8)phyId;
confRoutingInfo.reserved3[0] = 0;
confRoutingInfo.reserved3[1] = 0;
confRoutingInfo.disabledBit_reserved4 = 0;
confRoutingInfo.reserved5[0] = 0;
confRoutingInfo.reserved5[1] = 0;
confRoutingInfo.reserved5[2] = 0;
OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi);
OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo);
for ( i = 0; i < 16; i ++ )
{
confRoutingInfo.reserved6[i] = 0;
}
tdSMPStart(tiRoot, agRoot, oneExpander->tdDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ, agNULL, 0);
oneExpander->currentIndex[phyId] ++;
}
else
{
TI_DBG1(("tdsaSASRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
ret = agFALSE;
}
return ret;
}
osGLOBAL void
tdsaConfigRoutingInfoRespRcvd(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
tdsaDeviceData_t *oneDeviceData,
tdssSMPFrameHeader_t *frameHeader,
agsaFrameHandle_t frameHandle
)
{
tdsaExpander_t *oneExpander = oneDeviceData->tdExpander;
tdsaExpander_t *UpStreamExpander;
tdsaExpander_t *DownStreamExpander;
tdsaExpander_t *ReturningExpander;
tdsaExpander_t *ConfigurableExpander;
tdsaPortContext_t *onePortContext;
tdsaDeviceData_t *ReturningExpanderDeviceData;
bit32 dupConfigSASAddr = agFALSE;
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: start\n"));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
onePortContext = oneDeviceData->tdPortContext;
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
frameHeader->smpFunctionResult == PHY_VACANT
)
{
DownStreamExpander = oneExpander->tdCurrentDownStreamExpander;
if (DownStreamExpander != agNULL)
{
DownStreamExpander->currentUpStreamPhyIndex ++;
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressLo));
}
oneExpander->currentDownStreamPhyIndex++;
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
if ( DownStreamExpander != agNULL)
{
if (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: first if\n"));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
tdsaSASRoutingEntryAdd(tiRoot,
oneExpander,
DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
oneExpander->configSASAddressHi,
oneExpander->configSASAddressLo
);
}
else
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else\n"));
UpStreamExpander = oneExpander->tdUpStreamExpander;
ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
if (UpStreamExpander != agNULL)
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->tdDevice->SASAddressID.sasAddressLo));
dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
ConfigurableExpander,
oneExpander->configSASAddressHi,
oneExpander->configSASAddressLo
);
if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else if\n"));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo));
UpStreamExpander->tdCurrentDownStreamExpander = oneExpander;
ConfigurableExpander->currentDownStreamPhyIndex =
tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander);
ConfigurableExpander->tdReturnginExpander = oneExpander->tdReturnginExpander;
DownStreamExpander->currentUpStreamPhyIndex = 0;
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
tdsaSASRoutingEntryAdd(tiRoot,
ConfigurableExpander,
ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
oneExpander->configSASAddressHi,
oneExpander->configSASAddressLo
);
}
else
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n"));
ReturningExpander = oneExpander->tdReturnginExpander;
DownStreamExpander->currentUpStreamPhyIndex = 0;
if (ReturningExpander != agNULL)
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->tdDevice->SASAddressID.sasAddressLo));
ReturningExpanderDeviceData = ReturningExpander->tdDevice;
onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: More Phys to discover\n"));
if (ReturningExpander->discoverSMPAllowed == agTRUE)
{
tdsaDiscoverSend(tiRoot, ReturningExpanderDeviceData);
}
ReturningExpander->discoverSMPAllowed = agFALSE;
}
else
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: No More Phys\n"));
ReturningExpander->discoverSMPAllowed = agTRUE;
tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, ReturningExpander);
tdsaSASDownStreamDiscovering(tiRoot, onePortContext, ReturningExpanderDeviceData);
}
}
else
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander is NULL\n"));
}
}
}
else
{
TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n"));
}
}
}
}
else
{
TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=%x\n", frameHeader->smpFunctionResult));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
return;
}
osGLOBAL void
tdsaReportPhySataSend(
tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData,
bit8 phyId
)
{
agsaRoot_t *agRoot;
tdsaExpander_t *oneExpander;
tdsaPortContext_t *onePortContext;
smpReqReportPhySata_t smpReportPhySataReq;
TI_DBG3(("tdsaReportPhySataSend: start\n"));
agRoot = oneDeviceData->agRoot;
onePortContext = oneDeviceData->tdPortContext;
oneExpander = oneDeviceData->tdExpander;
if (onePortContext == agNULL)
{
TI_DBG1(("tdsaReportPhySataSend: Error!!! portcontext is NULL\n"));
}
if (oneExpander == agNULL)
{
TI_DBG1(("tdsaReportPhySataSend: Error!!! expander is NULL\n"));
return;
}
TI_DBG3(("tdsaReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
TI_DBG3(("tdsaReportPhySataSend: phyid %d\n", phyId));
oneExpander->tdDeviceToProcess = oneDeviceData;
osti_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t));
smpReportPhySataReq.phyIdentifier = phyId;
tdSMPStart(
tiRoot,
agRoot,
oneExpander->tdDevice,
SMP_REPORT_PHY_SATA,
(bit8 *)&smpReportPhySataReq,
sizeof(smpReqReportPhySata_t),
AGSA_SMP_INIT_REQ,
agNULL,
0
);
return;
}
osGLOBAL void
tdsaReportPhySataRcvd(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
tdsaDeviceData_t *oneDeviceData,
tdssSMPFrameHeader_t *frameHeader,
agsaFrameHandle_t frameHandle
)
{
smpRespReportPhySata_t SMPreportPhySataResp;
smpRespReportPhySata_t *pSMPReportPhySataResp;
tdsaExpander_t *oneExpander = oneDeviceData->tdExpander;
tdsaPortContext_t *onePortContext;
agsaFisRegDeviceToHost_t *fis;
tdsaDeviceData_t *SataDevice;
#ifndef DIRECT_SMP
tdssSMPRequestBody_t *tdSMPRequestBody;
#endif
TI_DBG3(("tdsaReportPhySataRcvd: start\n"));
TI_DBG3(("tdsaReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
#ifndef DIRECT_SMP
tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
#endif
SataDevice = oneExpander->tdDeviceToProcess;
pSMPReportPhySataResp = &SMPreportPhySataResp;
#ifdef DIRECT_SMP
saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
#else
saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
#endif
#ifndef DIRECT_SMP
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPReqosMemHandle,
tdSMPRequestBody->IndirectSMPReqLen
);
ostiFreeMemory(
tiRoot,
tdSMPRequestBody->IndirectSMPResposMemHandle,
tdSMPRequestBody->IndirectSMPRespLen
);
#endif
onePortContext = oneDeviceData->tdPortContext;
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaReportPhySataRcvd: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
if (SataDevice == agNULL)
{
TI_DBG1(("tdsaReportPhySataRcvd: SataDevice is NULL, wrong\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return;
}
if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
frameHeader->smpFunctionResult == PHY_VACANT
)
{
fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
{
TI_DBG3(("tdsaReportPhySataRcvd: saves the signature\n"));
SataDevice->satDevData.satSignature[0] = fis->d.sectorCount;
SataDevice->satDevData.satSignature[1] = fis->d.lbaLow;
SataDevice->satDevData.satSignature[2] = fis->d.lbaMid;
SataDevice->satDevData.satSignature[3] = fis->d.lbaHigh;
SataDevice->satDevData.satSignature[4] = fis->d.device;
SataDevice->satDevData.satSignature[5] = 0;
SataDevice->satDevData.satSignature[6] = 0;
SataDevice->satDevData.satSignature[7] = 0;
TI_DBG3(("tdsaReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
SataDevice->satDevData.satSignature[0],
SataDevice->satDevData.satSignature[1],
SataDevice->satDevData.satSignature[2],
SataDevice->satDevData.satSignature[3],
SataDevice->satDevData.satSignature[4]));
SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice);
tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice);
}
else
{
TI_DBG3(("tdsaReportPhySataRcvd: getting next stp bride\n"));
SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice);
tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice);
}
}
else
{
TI_DBG3(("tdsaReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n",
frameHeader->smpFunctionResult));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
return;
}
osGLOBAL void
tdsaSASExpanderUpStreamPhyAdd(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander,
bit8 phyId
)
{
bit32 i;
bit32 hasSet = agFALSE;
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: start, phyid %d\n", phyId));
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys));
for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ )
{
if ( oneExpander->upStreamPhys[i] == phyId )
{
hasSet = agTRUE;
break;
}
}
if ( hasSet == agFALSE )
{
oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId;
}
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys));
for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ )
{
TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i]));
}
return;
}
osGLOBAL void
tdsaSASExpanderDownStreamPhyAdd(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander,
bit8 phyId
)
{
bit32 i;
bit32 hasSet = agFALSE;
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: start, phyid %d\n", phyId));
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys));
for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ )
{
if ( oneExpander->downStreamPhys[i] == phyId )
{
hasSet = agTRUE;
break;
}
}
if ( hasSet == agFALSE )
{
oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId;
}
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys));
for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ )
{
TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i]));
}
return;
}
osGLOBAL bit16
tdsaFindCurrentDownStreamPhyIndex(
tiRoot_t *tiRoot,
tdsaExpander_t *oneExpander
)
{
tdsaExpander_t *DownStreamExpander;
bit16 index = 0;
bit16 i;
bit8 phyId = 0;
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: start\n"));
if (oneExpander == agNULL)
{
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! oneExpander is NULL\n"));
return 0;
}
DownStreamExpander = oneExpander->tdCurrentDownStreamExpander;
if (DownStreamExpander == agNULL)
{
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! DownStreamExpander is NULL\n"));
return 0;
}
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: downstream exp addrHi 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: downstream exp addrLo 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressLo));
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: numOfDownStreamPhys %d\n", oneExpander->numOfDownStreamPhys));
phyId = DownStreamExpander->upStreamPhys[0];
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: phyId %d\n", phyId));
for (i=0; i<oneExpander->numOfDownStreamPhys;i++)
{
if (oneExpander->downStreamPhys[i] == phyId)
{
index = i;
break;
}
}
TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: index %d\n", index));
return index;
}
osGLOBAL tdsaDeviceData_t *
tdsaPortSASDeviceFind(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
bit32 sasAddrLo,
bit32 sasAddrHi
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *oneDeviceData, *RetDeviceData=agNULL;
tdList_t *DeviceListList;
TI_DBG3(("tdsaPortSASDeviceFind: start\n"));
TD_ASSERT((agNULL != tiRoot), "");
TD_ASSERT((agNULL != onePortContext), "");
tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
DeviceListList = tdsaAllShared->MainDeviceList.flink;
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
TI_DBG3(("tdsaPortSASDeviceFind: Full discovery\n"));
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) &&
(oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) &&
(oneDeviceData->valid == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext)
)
{
TI_DBG3(("tdsaPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id));
TI_DBG3(("tdsaPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
RetDeviceData = oneDeviceData;
break;
}
DeviceListList = DeviceListList->flink;
}
}
else
{
TI_DBG3(("tdsaPortSASDeviceFind: Incremental discovery\n"));
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) &&
(oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) &&
(oneDeviceData->valid2 == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext)
)
{
TI_DBG3(("tdsaPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id));
TI_DBG3(("tdsaPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG3(("tdsaPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
RetDeviceData = oneDeviceData;
break;
}
DeviceListList = DeviceListList->flink;
}
}
tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
return RetDeviceData;
}
GLOBAL tdsaDeviceData_t *
tdsaPortSASDeviceAdd(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
agsaSASIdentify_t sasIdentify,
bit32 sasInitiator,
bit8 connectionRate,
bit32 itNexusTimeout,
bit32 firstBurstSize,
bit32 deviceType,
tdsaDeviceData_t *oneExpDeviceData,
bit8 phyID
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
bit8 dev_s_rate = 0;
bit8 sasorsata = 1;
tdsaSASSubID_t agSASSubID;
tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL;
TI_DBG3(("tdsaPortSASDeviceAdd: start\n"));
TI_DBG3(("tdsaPortSASDeviceAdd: connectionRate %d\n", connectionRate));
agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify);
agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify);
agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp;
agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp;
if ( agFALSE == tdssNewSASorNot(
onePortContext->agRoot,
onePortContext,
&agSASSubID
)
)
{
TI_DBG3(("tdsaPortSASDeviceAdd: OLD qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", agSASSubID.initiator_ssp_stp_smp, agSASSubID.target_ssp_stp_smp));
oneDeviceData = tdssNewAddSASToSharedcontext(
onePortContext->agRoot,
onePortContext,
&agSASSubID,
oneExpDeviceData,
phyID
);
if (oneDeviceData == agNULL)
{
TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n"));
}
if ( oneDeviceData != agNULL )
{
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify)));
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify)));
oneDeviceData->sasIdentify = sasIdentify;
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)));
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)));
DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT);
DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout);
DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize);
DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1);
oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify));
oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
if (oneAttachedExpDeviceData != agNULL)
{
connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
TI_DBG3(("tdsaPortSASDeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n",
connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
}
else
{
TI_DBG3(("tdsaPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n"));
}
sasorsata = (bit8)deviceType;
dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4));
dev_s_rate = (bit8)(dev_s_rate | connectionRate);
DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate);
DEVINFO_PUT_SAS_ADDRESSLO(
&oneDeviceData->agDeviceInfo,
SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)
);
DEVINFO_PUT_SAS_ADDRESSHI(
&oneDeviceData->agDeviceInfo,
SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)
);
oneDeviceData->agContext.osData = oneDeviceData;
oneDeviceData->agContext.sdkData = agNULL;
}
return oneDeviceData;
}
TI_DBG3(("tdsaPortSASDeviceAdd: NEW qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", agSASSubID.initiator_ssp_stp_smp, agSASSubID.target_ssp_stp_smp));
oneDeviceData = tdssNewAddSASToSharedcontext(
onePortContext->agRoot,
onePortContext,
&agSASSubID,
oneExpDeviceData,
phyID
);
if (oneDeviceData == agNULL)
{
TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n"));
}
if ( oneDeviceData != agNULL )
{
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify)));
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify)));
oneDeviceData->sasIdentify = sasIdentify;
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)));
TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)));
DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT);
DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout);
DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize);
DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1);
oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify));
oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
if (oneAttachedExpDeviceData != agNULL)
{
connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
TI_DBG3(("tdsaPortSASDeviceAdd: 2nd connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n",
connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
}
else
{
TI_DBG3(("tdsaPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n"));
}
sasorsata = (bit8)deviceType;
dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4));
dev_s_rate = (bit8)(dev_s_rate | connectionRate);
DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate);
DEVINFO_PUT_SAS_ADDRESSLO(
&oneDeviceData->agDeviceInfo,
SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)
);
DEVINFO_PUT_SAS_ADDRESSHI(
&oneDeviceData->agDeviceInfo,
SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)
);
oneDeviceData->agContext.osData = oneDeviceData;
oneDeviceData->agContext.sdkData = agNULL;
TI_DBG3(("tdsaPortSASDeviceAdd: did %d\n", oneDeviceData->id));
if ( (((sasIdentify.initiator_ssp_stp_smp & DEVICE_SSP_BIT) == DEVICE_SSP_BIT) &&
((sasIdentify.target_ssp_stp_smp & DEVICE_SSP_BIT) != DEVICE_SSP_BIT))
||
(((sasIdentify.initiator_ssp_stp_smp & DEVICE_STP_BIT) == DEVICE_STP_BIT) &&
((sasIdentify.target_ssp_stp_smp & DEVICE_SSP_BIT) != DEVICE_SSP_BIT))
)
{
TI_DBG1(("tdsaPortSASDeviceAdd: initiator. no add and registration\n"));
TI_DBG1(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)));
TI_DBG1(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)));
}
else
{
if (oneDeviceData->registered == agFALSE)
{
TI_DBG2(("tdsaPortSASDeviceAdd: did %d\n", oneDeviceData->id));
saRegisterNewDevice(
onePortContext->agRoot,
&oneDeviceData->agContext,
tdsaRotateQnumber(tiRoot, oneDeviceData),
&oneDeviceData->agDeviceInfo,
onePortContext->agPortContext,
0
);
}
}
}
return oneDeviceData;
}
osGLOBAL void
tdsaDiscoveryResetProcessed(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
TI_DBG6(("tdsaDiscoveryResetProcessed: start\n"));
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG6(("tdsaDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id));
if (oneDeviceData->tdPortContext == onePortContext)
{
TI_DBG6(("tdsaDiscoveryResetProcessed: resetting procssed flag\n"));
oneDeviceData->processed = agFALSE;
}
DeviceListList = DeviceListList->flink;
}
return;
}
osGLOBAL void
tdsaSATADiscoverDone(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
bit32 flag
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
TI_DBG3(("tdsaSATADiscoverDone: start\n"));
tdsaDiscoveryResetProcessed(tiRoot, onePortContext);
if (onePortContext->discovery.SeenBC == agTRUE)
{
TI_DBG3(("tdsaSATADiscoverDone: broadcast change; discover again\n"));
tdssInternalRemovals(onePortContext->agRoot,
onePortContext
);
onePortContext->discovery.SeenBC = agFALSE;
if (tdsaAllShared->ResetInDiscovery != 0 &&
onePortContext->discovery.ResetTriggerred == agTRUE)
{
TI_DBG1(("tdsaSATADiscoverDone: tdsaBCTimer\n"));
tdsaBCTimer(tiRoot, onePortContext);
}
else
{
tdsaDiscover(
tiRoot,
onePortContext,
TDSA_DISCOVERY_TYPE_SAS,
TDSA_DISCOVERY_OPTION_INCREMENTAL_START
);
}
}
else
{
onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
{
if (flag == tiSuccess)
{
#ifdef AGTIAPI_CTL
tdsaContext_t *tdsaAllShared =
&((tdsaRoot_t*)tiRoot->tdData)->tdsaAllShared;
if (tdsaAllShared->SASConnectTimeLimit)
tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery,
tiDiscOK);
else
#endif
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscOK,
agNULL
);
}
else
{
TI_DBG1(("tdsaSATADiscoverDone: Error; clean up\n"));
tdssDiscoveryErrorRemovals(onePortContext->agRoot,
onePortContext
);
ostiInitiatorEvent(
tiRoot,
onePortContext->tiPortalContext,
agNULL,
tiIntrEventTypeDiscovery,
tiDiscFailed,
agNULL
);
}
}
else
{
if (flag == tiSuccess)
{
tdssReportChanges(onePortContext->agRoot,
onePortContext
);
}
else
{
tdssReportRemovals(onePortContext->agRoot,
onePortContext,
agFALSE
);
}
}
}
#ifdef TBD
tdsaAckBC(tiRoot, onePortContext);
#endif
return;
}
osGLOBAL void
tdsaAckBC(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
#ifdef TBD
agsaEventSource_t eventSource[TD_MAX_NUM_PHYS];
bit32 HwAckSatus = AGSA_RC_SUCCESS;
int i;
TI_DBG3(("tdsaAckBC: start\n"));
for (i=0;i<TD_MAX_NUM_PHYS;i++)
{
if (onePortContext->BCPhyID[i] == agTRUE)
{
eventSource[i].agPortContext = onePortContext->agPortContext;
eventSource[i].event = OSSA_HW_EVENT_BROADCAST_CHANGE;
eventSource[i].param = i;
HwAckSatus = saHwEventAck(
onePortContext->agRoot,
agNULL,
0,
&eventSource[i],
0,
0
);
TI_DBG3(("tdsaAckBC: calling saHwEventAck\n"));
if ( HwAckSatus != AGSA_RC_SUCCESS)
{
TI_DBG1(("tdsaAckBC: failing in saHwEventAck; status %d\n", HwAckSatus));
return;
}
}
onePortContext->BCPhyID[i] = agFALSE;
}
#endif
}
#ifdef SATA_ENABLE
osGLOBAL bit32
tdsaSATAFullDiscover(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
bit32 ret = tiSuccess;
tdsaDeviceData_t *oneDeviceData = agNULL;
bit32 deviceType;
bit8 phyRate = SAS_CONNECTION_RATE_3_0G;
bit32 i;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *tdsaDeviceData;
tdList_t *DeviceListList;
TI_DBG3(("tdsaSATAFullDiscover: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSATAFullDiscover: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return tiError;
}
phyRate = onePortContext->LinkRate;
DeviceListList = tdsaAllShared->MainDeviceList.flink;
tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (onePortContext->nativeSATAMode == agTRUE)
{
deviceType = tdssSATADeviceTypeDecode(onePortContext->remoteSignature);
if ( deviceType == SATA_PM_DEVICE)
{
TI_DBG3(("tdsaSATAFullDiscover: Found a PM device\n"));
oneDeviceData = tdsaPortSATADeviceAdd(
tiRoot,
onePortContext,
agNULL,
onePortContext->remoteSignature,
agTRUE,
0xF,
phyRate,
agNULL,
0xFF
);
}
else
{
TI_DBG3(("tdsaSATAFullDiscover: Found a DIRECT SATA device\n"));
}
switch ( deviceType )
{
case SATA_PM_DEVICE:
{
TI_DBG3(("tdsaSATAFullDiscover: Process a PM device\n"));
for ( i = 0; i < SATA_MAX_PM_PORTS; i ++ )
{
}
break;
}
case SATA_ATA_DEVICE:
case SATA_ATAPI_DEVICE:
{
TI_DBG3(("tdsaSATAFullDiscover: Process an ATA device. Sending Identify Device cmd\n"));
tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess);
break;
}
default:
{
TI_DBG3(("siSATAFullDiscover: Process OTHER SATA device. Just report the device\n"));
break;
}
}
}
else
{
TI_DBG3(("tdsaSATAFullDiscover: Discovering attached STP devices starts....\n"));
oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
}
return ret;
}
GLOBAL tdsaDeviceData_t *
tdsaPortSATADeviceAdd(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneSTPBridge,
bit8 *Signature,
bit8 pm,
bit8 pmField,
bit8 connectionRate,
tdsaDeviceData_t *oneExpDeviceData,
bit8 phyID
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
agsaRoot_t *agRoot = onePortContext->agRoot;
bit8 dev_s_rate = 0;
bit8 sasorsata = SATA_DEVICE_TYPE;
bit8 flag = 0;
bit8 TLR = 0;
tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL;
TI_DBG3(("tdsaPortSATADeviceAdd: start\n"));
TD_ASSERT((agNULL != tiRoot), "");
TD_ASSERT((agNULL != agRoot), "");
TD_ASSERT((agNULL != onePortContext), "");
TD_ASSERT((agNULL != Signature), "");
oneDeviceData = tdssNewAddSATAToSharedcontext(
tiRoot,
agRoot,
onePortContext,
agNULL,
Signature,
pm,
pmField,
connectionRate,
oneExpDeviceData,
phyID
);
if (oneDeviceData == agNULL)
{
TI_DBG1(("tdsaPortSATADeviceAdd: no more device!!! oneDeviceData is null\n"));
return agNULL;
}
flag = (bit8)((phyID << 4) | TLR);
DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT);
DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, 0xFFF);
DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, 0);
DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, flag);
oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
if (oneAttachedExpDeviceData != agNULL)
{
connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
TI_DBG3(("tdsaPortSATADeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n",
connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)));
}
else
{
TI_DBG3(("tdsaPortSATADeviceAdd: 1st oneAttachedExpDeviceData is NULL\n"));
}
dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4));
dev_s_rate = (bit8)(dev_s_rate | connectionRate);
DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate);
osti_memset(&oneDeviceData->agDeviceInfo.sasAddressHi, 0, 4);
osti_memset(&oneDeviceData->agDeviceInfo.sasAddressLo, 0, 4);
oneDeviceData->agContext.osData = oneDeviceData;
oneDeviceData->agContext.sdkData = agNULL;
TI_DBG1(("tdsaPortSATADeviceAdd: did %d\n", oneDeviceData->id));
if (oneDeviceData->registered == agFALSE)
{
TI_DBG2(("tdsaPortSATADeviceAdd: did %d\n", oneDeviceData->id));
saRegisterNewDevice(
onePortContext->agRoot,
&oneDeviceData->agContext,
tdsaRotateQnumber(tiRoot, oneDeviceData),
&oneDeviceData->agDeviceInfo,
onePortContext->agPortContext,
0
);
}
return oneDeviceData;
}
#endif
osGLOBAL tdsaDeviceData_t *
tdsaFindRightDevice(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *tdsaDeviceData
)
{
tdList_t *DeviceListList;
tdsaDeviceData_t *oneDeviceData = agNULL;
bit32 found = agFALSE;
TI_DBG3(("tdsaFindHeadDevice: start\n"));
DeviceListList = tdsaDeviceData->MainLink.flink;
while (DeviceListList != &(tdsaDeviceData->MainLink))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG3(("tdsaFindRightDevice: did %d STP %d SATA %d \n", onePortContext->id, DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData)));
DeviceListList = DeviceListList->flink;
}
DeviceListList = tdsaDeviceData->MainLink.flink;
while (DeviceListList != &(tdsaDeviceData->MainLink))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if ((oneDeviceData->registered == agTRUE) &&
(oneDeviceData->tdPortContext == onePortContext) &&
(oneDeviceData->processed == agFALSE) &&
(SA_IDFRM_IS_STP_TARGET(&oneDeviceData->sasIdentify) ||
SA_IDFRM_IS_SATA_DEVICE(&oneDeviceData->sasIdentify))
)
{
TI_DBG3(("tdsaFindRightDevice: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
oneDeviceData->processed = agTRUE;
found = agTRUE;
break;
}
DeviceListList = DeviceListList->flink;
}
if (found == agTRUE)
{
return oneDeviceData;
}
else
{
return agNULL;
}
}
osGLOBAL void
tdsaDiscoveringStpSATADevice(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
bit32 status;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *tdsaDeviceData;
tdList_t *DeviceListList;
TI_DBG3(("tdsaDiscoveringStpSATADevice: start\n"));
DeviceListList = tdsaAllShared->MainDeviceList.flink;
tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData)
{
TI_DBG3(("tdsaDiscoveringStpSATADevice: Found STP-SATA Device=%p\n", oneDeviceData));
if ((SA_IDFRM_IS_SATA_DEVICE(&oneDeviceData->sasIdentify) || SA_IDFRM_IS_STP_TARGET(&oneDeviceData->sasIdentify))
&&
((onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START &&
oneDeviceData->valid == agTRUE) ||
(onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START &&
oneDeviceData->valid2 == agTRUE)) &&
(oneDeviceData->tdPortContext == onePortContext)
)
{
TI_DBG3(("tdsaDiscoveringStpSATADevice: sending report phy sata\n"));
tdsaReportPhySataSend(tiRoot, oneDeviceData, oneDeviceData->sasIdentify.phyIdentifier);
if (oneDeviceData->satDevData.IDDeviceValid == agFALSE)
{
TI_DBG3(("tdsaDiscoveringStpSATADevice: sending identify device data\n"));
status = tdsaDiscoveryStartIDDev(tiRoot,
agNULL,
&(oneDeviceData->tiDeviceHandle),
agNULL,
oneDeviceData);
if (status != tiSuccess)
{
TI_DBG1(("tdsaDiscoveringStpSATADevice: fail or busy %d\n", status));
oneDeviceData->satDevData.IDDeviceValid = agFALSE;
}
}
}
else
{
TI_DBG2(("tdsaDiscoveringStpSATADevice: moving to the next\n"));
oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
TI_DBG3(("tdsaDiscoveringStpSATADevice: No More Device; SATA discovery finished\n"));
tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess);
}
return;
}
osGLOBAL bit32
tdsaSASIncrementalDiscover(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaDeviceData_t *oneDeviceData = agNULL;
int i,j;
bit8 portMaxRate;
TI_DBG3(("tdsaSASIncrementalDiscover: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSASIncrementalDiscover: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return tiError;
}
onePortContext->DiscoveryState = ITD_DSTATE_STARTED;
if (onePortContext->nativeSATAMode == agFALSE)
{
if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE &&
SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) )
{
for(i=0;i<TD_MAX_NUM_PHYS;i++)
{
if (onePortContext->PhyIDList[i] == agTRUE)
{
for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++)
{
saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL);
}
break;
}
}
}
portMaxRate = onePortContext->LinkRate;
oneDeviceData = tdsaPortSASDeviceAdd(
tiRoot,
onePortContext,
onePortContext->sasIDframe,
agFALSE,
portMaxRate,
IT_NEXUS_TIMEOUT,
0,
SAS_DEVICE_TYPE,
agNULL,
0xFF
);
if (oneDeviceData)
{
if (oneDeviceData->registered == agFALSE)
{
tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
}
else
{
tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
}
}
}
else
{
tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
}
return tiSuccess;
}
#ifdef SATA_ENABLE
osGLOBAL bit32
tdsaSATAIncrementalDiscover(
tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
bit32 ret = tiSuccess;
tdsaDeviceData_t *oneDeviceData = agNULL;
bit32 deviceType;
bit8 phyRate = SAS_CONNECTION_RATE_3_0G;
bit32 i;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdsaDeviceData_t *tdsaDeviceData;
tdList_t *DeviceListList;
TI_DBG3(("tdsaSATAIncrementalDiscover: start\n"));
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaSATAIncrementalDiscover: aborting discovery\n"));
tdsaSASDiscoverAbort(tiRoot, onePortContext);
return tiError;
}
DeviceListList = tdsaAllShared->MainDeviceList.flink;
tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
if (onePortContext->nativeSATAMode == agTRUE)
{
deviceType = tdssSATADeviceTypeDecode(onePortContext->remoteSignature);
if ( deviceType == SATA_PM_DEVICE)
{
TI_DBG3(("tdsaSATAIncrementalDiscover: Found a PM device\n"));
oneDeviceData = tdsaPortSATADeviceAdd(
tiRoot,
onePortContext,
agNULL,
onePortContext->remoteSignature,
agTRUE,
0xF,
phyRate,
agNULL,
0xFF);
}
else
{
TI_DBG3(("tdsaSATAIncrementalDiscover: Found a DIRECT SATA device\n"));
}
switch ( deviceType )
{
case SATA_PM_DEVICE:
{
TI_DBG3(("tdsaSATAIncrementalDiscover: Process a PM device\n"));
for ( i = 0; i < SATA_MAX_PM_PORTS; i ++ )
{
}
break;
}
case SATA_ATA_DEVICE:
case SATA_ATAPI_DEVICE:
{
TI_DBG3(("tdsaSATAIncrementalDiscover: Process an ATA device. Sending Identify Device cmd\n"));
tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess);
break;
}
default:
{
TI_DBG3(("siSATAIncrementalDiscover: Process OTHER SATA device. Just report the device\n"));
break;
}
}
}
else
{
TI_DBG3(("tdsaSATAIncrementalDiscover: Discovering attached STP devices starts....\n"));
oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
}
return ret;
}
#endif
osGLOBAL bit32
tdSMPStart(
tiRoot_t *tiRoot,
agsaRoot_t *agRoot,
tdsaDeviceData_t *oneDeviceData,
bit32 functionCode,
bit8 *pSmpBody,
bit32 smpBodySize,
bit32 agRequestType,
tiIORequest_t *CurrentTaskTag,
bit32 queueNumber
)
{
void *osMemHandle;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
bit32 expectedRspLen = 0;
#ifdef REMOVED
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
#endif
tdssSMPRequestBody_t *tdSMPRequestBody;
agsaSASRequestBody_t *agSASRequestBody;
agsaSMPFrame_t *agSMPFrame;
agsaIORequest_t *agIORequest;
agsaDevHandle_t *agDevHandle;
tdssSMPFrameHeader_t tdSMPFrameHeader;
tdsaPortContext_t *onePortContext = agNULL;
bit32 status;
#ifndef DIRECT_SMP
void *IndirectSMPReqosMemHandle;
bit32 IndirectSMPReqPhysUpper32;
bit32 IndirectSMPReqPhysLower32;
bit32 IndirectSMPReqmemAllocStatus;
bit8 *IndirectSMPReq;
void *IndirectSMPResposMemHandle;
bit32 IndirectSMPRespPhysUpper32;
bit32 IndirectSMPRespPhysLower32;
bit32 IndirectSMPRespmemAllocStatus;
bit8 *IndirectSMPResp;
#endif
TI_DBG3(("tdSMPStart: start\n"));
TI_DBG3(("tdSMPStart: oneDeviceData %p\n", oneDeviceData));
TI_DBG3(("tdSMPStart: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)));
TI_DBG3(("tdSMPStart: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)));
TI_DBG3(("tdSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
TI_DBG3(("tdSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
onePortContext = oneDeviceData->tdPortContext;
if (onePortContext != agNULL)
{
TI_DBG3(("tdSMPStart: pid %d\n", onePortContext->id));
onePortContext->discovery.pendingSMP++;
}
else
{
TI_DBG1(("tdSMPStart: Wrong!!! onePortContext is NULL\n"));
return tiError;
}
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdSMPRequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdssSMPRequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory failed...\n"));
return tiError;
}
if (tdSMPRequestBody == agNULL)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL tdSMPRequestBody\n"));
return tiError;
}
tdSMPRequestBody->osMemHandle = osMemHandle;
tdSMPRequestBody->tdDevice = oneDeviceData;
tdSMPRequestBody->tdPortContext = onePortContext;
agDevHandle = oneDeviceData->agDevHandle;
tdSMPRequestBody->SMPCompletionFunc = itdssSMPCompleted;
tdSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
tdSMPRequestBody->retries = 0;
#ifdef TD_INTERNAL_DEBUG
TI_DBG4(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody));
TI_DBG4(("tdSMPStart: callback fn %p\n", tdSMPRequestBody->SMPCompletionFunc));
#endif
agIORequest = &(tdSMPRequestBody->agIORequest);
agIORequest->osData = (void *) tdSMPRequestBody;
agIORequest->sdkData = agNULL;
agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody);
agSMPFrame = &(agSASRequestBody->smpFrame);
TI_DBG3(("tdSMPStart: agIORequest %p\n", agIORequest));
TI_DBG3(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody));
switch (functionCode)
{
case SMP_REPORT_GENERAL:
expectedRspLen = sizeof(smpRespReportGeneral_t) + 4;
break;
case SMP_REPORT_MANUFACTURE_INFORMATION:
expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4;
break;
case SMP_DISCOVER:
expectedRspLen = sizeof(smpRespDiscover_t) + 4;
break;
case SMP_REPORT_PHY_ERROR_LOG:
expectedRspLen = 32 - 4;
break;
case SMP_REPORT_PHY_SATA:
expectedRspLen = sizeof(smpRespReportPhySata_t) + 4;
break;
case SMP_REPORT_ROUTING_INFORMATION:
expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4;
break;
case SMP_CONFIGURE_ROUTING_INFORMATION:
expectedRspLen = 4;
break;
case SMP_PHY_CONTROL:
expectedRspLen = 4;
break;
case SMP_PHY_TEST_FUNCTION:
expectedRspLen = 4;
break;
case SMP_PMC_SPECIFIC:
expectedRspLen = 4;
break;
default:
expectedRspLen = 0;
TI_DBG1(("tdSMPStart: error!!! undefined or unused smp function code 0x%x\n", functionCode));
return tiError;
}
if (tiIS_SPC(agRoot))
{
#ifdef DIRECT_SMP
if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT)
{
TI_DBG3(("tdSMPStart: DIRECT smp payload\n"));
osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));
osti_memset(tdSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
tdSMPFrameHeader.smpFrameType = SMP_REQUEST;
tdSMPFrameHeader.smpFunction = (bit8)functionCode;
tdSMPFrameHeader.smpFunctionResult = 0;
tdSMPFrameHeader.smpReserved = 0;
osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4);
osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize);
agSMPFrame->outFrameBuf = tdSMPRequestBody->smpPayload;
agSMPFrame->outFrameLen = smpBodySize + 4;
agSMPFrame->inFrameLen = 0;
#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
agSMPFrame->expectedRespLen = 0;
#else
agSMPFrame->expectedRespLen = expectedRspLen;
#endif
}
else
{
TI_DBG3(("tdSMPStart: INDIRECT smp payload\n"));
}
#else
IndirectSMPReqmemAllocStatus = ostiAllocMemory(
tiRoot,
&IndirectSMPReqosMemHandle,
(void **)&IndirectSMPReq,
&IndirectSMPReqPhysUpper32,
&IndirectSMPReqPhysLower32,
8,
smpBodySize + 4,
agFALSE
);
if (IndirectSMPReqmemAllocStatus != tiSuccess)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP request...\n"));
return tiError;
}
if (IndirectSMPReq == agNULL)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPReq\n"));
return tiError;
}
IndirectSMPRespmemAllocStatus = ostiAllocMemory(
tiRoot,
&IndirectSMPResposMemHandle,
(void **)&IndirectSMPResp,
&IndirectSMPRespPhysUpper32,
&IndirectSMPRespPhysLower32,
8,
expectedRspLen,
agFALSE
);
if (IndirectSMPRespmemAllocStatus != tiSuccess)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP reponse...\n"));
return tiError;
}
if (IndirectSMPResp == agNULL)
{
TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPResp\n"));
return tiError;
}
tdSMPRequestBody->IndirectSMPReqosMemHandle = IndirectSMPReqosMemHandle;
tdSMPRequestBody->IndirectSMPResposMemHandle = IndirectSMPResposMemHandle;
tdSMPRequestBody->IndirectSMPReq = IndirectSMPReq;
tdSMPRequestBody->IndirectSMPResp = IndirectSMPResp;
tdSMPRequestBody->IndirectSMPReqLen = smpBodySize + 4;
tdSMPRequestBody->IndirectSMPRespLen = expectedRspLen;
TI_DBG3(("tdSMPStart: INDIRECT smp payload\n"));
osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));
osti_memset(IndirectSMPReq, 0, smpBodySize + 4);
osti_memset(IndirectSMPResp, 0, expectedRspLen);
tdSMPFrameHeader.smpFrameType = SMP_REQUEST;
tdSMPFrameHeader.smpFunction = (bit8)functionCode;
tdSMPFrameHeader.smpFunctionResult = 0;
tdSMPFrameHeader.smpReserved = 0;
osti_memcpy(IndirectSMPReq, &tdSMPFrameHeader, 4);
osti_memcpy(IndirectSMPReq+4, pSmpBody, smpBodySize);
agSMPFrame->outFrameBuf = agNULL;
agSMPFrame->outFrameAddrUpper32 = IndirectSMPReqPhysUpper32;
agSMPFrame->outFrameAddrLower32 = IndirectSMPReqPhysLower32;
agSMPFrame->outFrameLen = smpBodySize + 4;
agSMPFrame->expectedRespLen = expectedRspLen;
agSMPFrame->inFrameLen = expectedRspLen;
agSMPFrame->inFrameAddrUpper32 = IndirectSMPRespPhysUpper32;
agSMPFrame->inFrameAddrLower32 = IndirectSMPRespPhysLower32;
#endif
}
else
{
TI_DBG3(("tdSMPStart: DIRECT smp payload\n"));
agSMPFrame->flag = 0;
osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));
osti_memset(tdSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
tdSMPFrameHeader.smpFrameType = SMP_REQUEST;
tdSMPFrameHeader.smpFunction = (bit8)functionCode;
tdSMPFrameHeader.smpFunctionResult = 0;
tdSMPFrameHeader.smpReserved = 0;
osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4);
osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize);
agSMPFrame->outFrameBuf = tdSMPRequestBody->smpPayload;
agSMPFrame->outFrameLen = smpBodySize + 4;
agSMPFrame->inFrameLen = 0;
#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
agSMPFrame->expectedRespLen = 0;
#else
agSMPFrame->expectedRespLen = expectedRspLen;
#endif
}
if (agDevHandle == agNULL)
{
TI_DBG1(("tdSMPStart: !!! agDevHandle is NULL !!! \n"));
return tiError;
}
tdSMPRequestBody->queueNumber = queueNumber;
status = saSMPStart(
agRoot,
agIORequest,
queueNumber,
agDevHandle,
agRequestType,
agSASRequestBody,
&ossaSMPCompleted
);
if (status == AGSA_RC_SUCCESS)
{
if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION
)
{
tdsaDiscoverySMPTimer(tiRoot, onePortContext, functionCode, tdSMPRequestBody);
}
return tiSuccess;
}
else if (status == AGSA_RC_BUSY)
{
if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
{
tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody);
return tiSuccess;
}
else if (functionCode == SMP_PHY_CONTROL)
{
ostiFreeMemory(
tiRoot,
osMemHandle,
sizeof(tdssSMPRequestBody_t)
);
return tiBusy;
}
else
{
ostiFreeMemory(
tiRoot,
osMemHandle,
sizeof(tdssSMPRequestBody_t)
);
return tiBusy;
}
}
else
{
if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
{
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
}
ostiFreeMemory(
tiRoot,
osMemHandle,
sizeof(tdssSMPRequestBody_t)
);
return tiError;
}
}
#ifdef REMOVED
osGLOBAL bit8
tdsaFindLocalLinkRate(
tiRoot_t *tiRoot,
tdsaPortStartInfo_t *tdsaPortStartInfo
)
{
bit8 ans = SAS_CONNECTION_RATE_3_0G;
bit32 phyProperties;
phyProperties = tdsaPortStartInfo->agPhyConfig.phyProperties;
TI_DBG3(("tdsaFindLocalLinkRate: start\n"));
if (phyProperties & 0x4)
{
ans = SAS_CONNECTION_RATE_6_0G;
}
if (phyProperties & 0x2)
{
ans = SAS_CONNECTION_RATE_3_0G;
}
if (phyProperties & 0x1)
{
ans = SAS_CONNECTION_RATE_1_5G;
}
TI_DBG3(("tdsaFindLocalLinkRate: ans 0x%x\n", ans));
return ans;
}
#endif
osGLOBAL void
tdsaConfigureRouteTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaExpander_t *oneExpander,
smpRespDiscover_t *ptdSMPDiscoverResp
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaConfigureRouteTimer: start\n"));
TI_DBG1(("tdsaConfigureRouteTimer: pid %d\n", onePortContext->id));
discovery = &(onePortContext->discovery);
TI_DBG1(("tdsaConfigureRouteTimer: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp));
TI_DBG1(("tdsaConfigureRouteTimer: discovery %p \n", discovery));
TI_DBG1(("tdsaConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries));
TI_DBG1(("tdsaConfigureRouteTimer: discovery->status %d\n", discovery->status));
if (discovery->configureRouteTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->configureRouteTimer
);
}
TI_DBG1(("tdsaConfigureRouteTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
TI_DBG1(("tdsaConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
tdsaSetTimerRequest(
tiRoot,
&discovery->configureRouteTimer,
CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaConfigureRouteTimerCB,
(void *)onePortContext,
(void *)oneExpander,
(void *)ptdSMPDiscoverResp
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->configureRouteTimer
);
return;
}
osGLOBAL void
tdsaConfigureRouteTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaPortContext_t *onePortContext;
tdsaExpander_t *oneExpander;
smpRespDiscover_t *ptdSMPDiscoverResp;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaConfigureRouteTimerCB: start\n"));
onePortContext = (tdsaPortContext_t *)timerData1;
oneExpander = (tdsaExpander_t *)timerData2;
ptdSMPDiscoverResp = (smpRespDiscover_t *)timerData3;
discovery = &(onePortContext->discovery);
TI_DBG1(("tdsaConfigureRouteTimerCB: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp));
TI_DBG1(("tdsaConfigureRouteTimerCB: discovery %p\n", discovery));
TI_DBG1(("tdsaConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries));
TI_DBG1(("tdsaConfigureRouteTimerCB: discovery.status %d\n", discovery->status));
discovery->configureRouteRetries++;
if (discovery->configureRouteRetries >= DISCOVERY_RETRIES)
{
TI_DBG1(("tdsaConfigureRouteTimerCB: retries are over\n"));
discovery->configureRouteRetries = 0;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
if (discovery->configureRouteTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->configureRouteTimer
);
}
return;
}
if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
{
TI_DBG1(("tdsaConfigureRouteTimerCB: proceed by calling tdsaSASDownStreamDiscoverExpanderPhy\n"));
tdhexdump("tdsaConfigureRouteTimerCB", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
discovery->configureRouteRetries = 0;
tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
}
else
{
TI_DBG1(("tdsaConfigureRouteTimerCB: setting timer again\n"));
tdsaSetTimerRequest(
tiRoot,
&discovery->configureRouteTimer,
CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaConfigureRouteTimerCB,
(void *)onePortContext,
(void *)oneExpander,
(void *)ptdSMPDiscoverResp
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->configureRouteTimer
);
}
return;
}
osGLOBAL void
tdsaDiscoveryTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaDiscoveryTimer: start\n"));
TI_DBG1(("tdsaDiscoveryTimer: pid %d\n", onePortContext->id));
discovery = &(onePortContext->discovery);
if (discovery->discoveryTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->discoveryTimer
);
}
TI_DBG1(("tdsaDiscoveryTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
TI_DBG1(("tdsaDiscoveryTimer: Timervalue %d\n", DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
tdsaSetTimerRequest(
tiRoot,
&discovery->discoveryTimer,
DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaDiscoveryTimerCB,
oneDeviceData,
agNULL,
agNULL
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->discoveryTimer
);
return;
}
osGLOBAL void
tdsaDiscoveryTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaDeviceData_t *oneDeviceData;
oneDeviceData = (tdsaDeviceData_t *)timerData1;
TI_DBG1(("tdsaDiscoveryTimerCB: start\n"));
if (oneDeviceData->registered == agTRUE)
{
TI_DBG1(("tdsaDiscoveryTimerCB: resumes discovery\n"));
tdsaReportGeneralSend(tiRoot, oneDeviceData);
}
return;
}
osGLOBAL void
tdsaDeviceRegistrationTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaDeviceRegistrationTimer: start\n"));
TI_DBG1(("tdsaDeviceRegistrationTimer: pid %d\n", onePortContext->id));
discovery = &(onePortContext->discovery);
if (discovery->deviceRegistrationTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->deviceRegistrationTimer
);
}
TI_DBG1(("tdsaDeviceRegistrationTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
TI_DBG1(("tdsaDeviceRegistrationTimer: Timervalue %d\n", DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
tdsaSetTimerRequest(
tiRoot,
&discovery->deviceRegistrationTimer,
DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaDeviceRegistrationTimerCB,
onePortContext,
oneDeviceData,
agNULL
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->deviceRegistrationTimer
);
return;
}
osGLOBAL void
tdsaDeviceRegistrationTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaPortContext_t *onePortContext;
tdsaDeviceData_t *oneDeviceData;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaDeviceRegistrationTimerCB: start\n"));
onePortContext = (tdsaPortContext_t *)timerData1;
oneDeviceData = (tdsaDeviceData_t *)timerData2;
discovery = &(onePortContext->discovery);
if (oneDeviceData->registered == agFALSE)
{
discovery->deviceRetistrationRetries++;
if (discovery->deviceRetistrationRetries >= DISCOVERY_RETRIES)
{
TI_DBG1(("tdsaDeviceRegistrationTimerCB: retries are over\n"));
discovery->deviceRetistrationRetries = 0;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
if (discovery->deviceRegistrationTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->deviceRegistrationTimer
);
}
}
else
{
TI_DBG1(("tdsaDeviceRegistrationTimerCB: keep retrying\n"));
tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
}
}
else
{
discovery->deviceRetistrationRetries = 0;
tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
}
}
osGLOBAL void
tdsaSMPBusyTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
tdsaDeviceData_t *oneDeviceData,
tdssSMPRequestBody_t *tdSMPRequestBody
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaSMPBusyTimer: start\n"));
TI_DBG1(("tdsaSMPBusyTimer: pid %d\n", onePortContext->id));
discovery = &(onePortContext->discovery);
if (discovery->SMPBusyTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->SMPBusyTimer
);
}
tdsaSetTimerRequest(
tiRoot,
&discovery->SMPBusyTimer,
SMP_BUSY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaSMPBusyTimerCB,
onePortContext,
oneDeviceData,
tdSMPRequestBody
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->SMPBusyTimer
);
return;
}
osGLOBAL void
tdsaSMPBusyTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
agsaRoot_t *agRoot;
tdsaPortContext_t *onePortContext;
tdsaDeviceData_t *oneDeviceData;
tdssSMPRequestBody_t *tdSMPRequestBody;
agsaSASRequestBody_t *agSASRequestBody;
agsaIORequest_t *agIORequest;
agsaDevHandle_t *agDevHandle;
tdsaDiscovery_t *discovery;
bit32 status = AGSA_RC_FAILURE;
TI_DBG1(("tdsaSMPBusyTimerCB: start\n"));
onePortContext = (tdsaPortContext_t *)timerData1;
oneDeviceData = (tdsaDeviceData_t *)timerData2;
tdSMPRequestBody = (tdssSMPRequestBody_t *)timerData3;
agRoot = oneDeviceData->agRoot;
agIORequest = &(tdSMPRequestBody->agIORequest);
agDevHandle = oneDeviceData->agDevHandle;
agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody);
discovery = &(onePortContext->discovery);
discovery->SMPRetries++;
if (discovery->SMPRetries < SMP_BUSY_RETRIES)
{
status = saSMPStart(
agRoot,
agIORequest,
tdsaAllShared->SMPQNum,
agDevHandle,
AGSA_SMP_INIT_REQ,
agSASRequestBody,
&ossaSMPCompleted
);
}
if (status == AGSA_RC_SUCCESS)
{
discovery->SMPRetries = 0;
if (discovery->SMPBusyTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->SMPBusyTimer
);
}
}
else if (status == AGSA_RC_FAILURE)
{
discovery->SMPRetries = 0;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
if (discovery->SMPBusyTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->SMPBusyTimer
);
}
}
else
{
if (discovery->SMPRetries >= SMP_BUSY_RETRIES)
{
TI_DBG1(("tdsaSMPBusyTimerCB: retries are over\n"));
discovery->SMPRetries = 0;
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
if (discovery->SMPBusyTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->SMPBusyTimer
);
}
}
else
{
tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody);
}
}
return;
}
osGLOBAL void
tdsaBCTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaBCTimer: start\n"));
discovery = &(onePortContext->discovery);
if (discovery->BCTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->BCTimer
);
}
if (onePortContext->valid == agTRUE)
{
tdsaSetTimerRequest(
tiRoot,
&discovery->BCTimer,
BC_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaBCTimerCB,
onePortContext,
agNULL,
agNULL
);
tdsaAddTimer(
tiRoot,
&Initiator->timerlist,
&discovery->BCTimer
);
}
return;
}
osGLOBAL void
tdsaBCTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaPortContext_t *onePortContext;
tdsaDiscovery_t *discovery;
TI_DBG1(("tdsaBCTimerCB: start\n"));
onePortContext = (tdsaPortContext_t *)timerData1;
discovery = &(onePortContext->discovery);
discovery->ResetTriggerred = agFALSE;
if (onePortContext->valid == agTRUE)
{
tdsaDiscover(
tiRoot,
onePortContext,
TDSA_DISCOVERY_TYPE_SAS,
TDSA_DISCOVERY_OPTION_INCREMENTAL_START
);
}
if (discovery->BCTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->BCTimer
);
}
return;
}
osGLOBAL void
tdsaDiscoverySMPTimer(tiRoot_t *tiRoot,
tdsaPortContext_t *onePortContext,
bit32 functionCode,
tdssSMPRequestBody_t *tdSMPRequestBody
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDiscovery_t *discovery;
TI_DBG3(("tdsaDiscoverySMPTimer: start\n"));
TI_DBG3(("tdsaDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode));
discovery = &(onePortContext->discovery);
if (discovery->DiscoverySMPTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->DiscoverySMPTimer
);
}
tdsaSetTimerRequest(
tiRoot,
&discovery->DiscoverySMPTimer,
SMP_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaDiscoverySMPTimerCB,
onePortContext,
tdSMPRequestBody,
agNULL
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&discovery->DiscoverySMPTimer
);
return;
}
osGLOBAL void
tdsaDiscoverySMPTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
agsaRoot_t *agRoot;
tdsaPortContext_t *onePortContext;
bit8 SMPFunction;
#ifndef DIRECT_SMP
tdssSMPFrameHeader_t *tdSMPFrameHeader;
bit8 smpHeader[4];
#endif
tdssSMPRequestBody_t *tdSMPRequestBody;
tdsaDiscovery_t *discovery;
tdsaDeviceData_t *oneDeviceData;
agsaIORequest_t *agAbortIORequest = agNULL;
tdIORequestBody_t *tdAbortIORequestBody = agNULL;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
agsaIORequest_t *agToBeAbortIORequest = agNULL;
TI_DBG1(("tdsaDiscoverySMPTimerCB: start\n"));
onePortContext = (tdsaPortContext_t *)timerData1;
tdSMPRequestBody = (tdssSMPRequestBody_t *)timerData2;
discovery = &(onePortContext->discovery);
oneDeviceData = tdSMPRequestBody->tdDevice;
agToBeAbortIORequest = &(tdSMPRequestBody->agIORequest);
agRoot = oneDeviceData->agRoot;
#ifdef DIRECT_SMP
SMPFunction = tdSMPRequestBody->smpPayload[1];
#else
saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 0, smpHeader, 4);
tdSMPFrameHeader = (tdssSMPFrameHeader_t *)smpHeader;
SMPFunction = tdSMPFrameHeader->smpFunction;
#endif
TI_DBG1(("tdsaDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction));
if (discovery->DiscoverySMPTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&discovery->DiscoverySMPTimer
);
}
switch (SMPFunction)
{
case SMP_REPORT_GENERAL:
case SMP_DISCOVER:
case SMP_CONFIGURE_ROUTING_INFORMATION:
TI_DBG1(("tdsaDiscoverySMPTimerCB: failing discovery, SMP function 0x%x\n", SMPFunction));
tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
return;
case SMP_REPORT_PHY_SATA:
TI_DBG1(("tdsaDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA\n"));
tdsaSATADiscoverDone(tiRoot, onePortContext, tiError);
break;
default:
TI_DBG1(("tdsaDiscoverySMPTimerCB: Error!!!! not allowed case\n"));
break;
}
if (onePortContext->discovery.SeenBC == agTRUE)
{
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory failed...\n"));
return;
}
if (tdAbortIORequestBody == agNULL)
{
TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
return;
}
tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler;
tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle);
agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) tdAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
saSMPAbort(agRoot,
agAbortIORequest,
0,
oneDeviceData->agDevHandle,
0,
agToBeAbortIORequest,
agNULL
);
}
return;
}
osGLOBAL void
tdsaSATAIDDeviceTimer(tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
TI_DBG1(("tdsaSATAIDDeviceTimer: start\n"));
if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&oneDeviceData->SATAIDDeviceTimer
);
}
tdsaSetTimerRequest(
tiRoot,
&oneDeviceData->SATAIDDeviceTimer,
SATA_ID_DEVICE_DATA_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
tdsaSATAIDDeviceTimerCB,
oneDeviceData,
agNULL,
agNULL
);
tdsaAddTimer (
tiRoot,
&Initiator->timerlist,
&oneDeviceData->SATAIDDeviceTimer
);
return;
}
osGLOBAL void
tdsaSATAIDDeviceTimerCB(
tiRoot_t * tiRoot,
void * timerData1,
void * timerData2,
void * timerData3
)
{
tdsaDeviceData_t *oneDeviceData;
TI_DBG1(("tdsaSATAIDDeviceTimerCB: start\n"));
oneDeviceData = (tdsaDeviceData_t *)timerData1;
tdssSubAddSATAToSharedcontext(tiRoot, oneDeviceData);
if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE)
{
tdsaKillTimer(
tiRoot,
&oneDeviceData->SATAIDDeviceTimer
);
}
return;
}
#endif