⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mvstoragedev.c

📁 此为marvell6081芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/*******************************************************************************
* mvPMDevReadReg - Reads port multiplier's internal register
*                  
*
* DESCRIPTION:
*       Performs PIO non-data command for reading port multiplier's internal
*       register.
*
* INPUT:
*       pAdapter            - Pointer to the device data structure.
*       channelIndex        - Index of the required channel
*       PMPort              - This should be port 0xf
*       PMReg               - The required register to be read
*       pValue              - A pointer to 32bit data container that holds
*                             the result.
*       registerStruct      - A pointer to ATA register data structure. This
*                             holds the ATA registers dump after command
*                             is executed.
*
* RETURN:
*       MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
*       NONE
*
*******************************************************************************/
MV_BOOLEAN  mvPMDevReadReg(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
                           MV_U8 PMPort, MV_U8 PMReg, MV_U32 *pValue,
                           MV_STORAGE_DEVICE_REGISTERS *registerStruct)
{
    MV_SATA_CHANNEL *pSataChannel;
    MV_BOOLEAN      result;

    if (pAdapter == NULL)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "    :  mvStorageDevPMReadReg"
                 " Failed, Bad adapter data structure pointer\n");
        return MV_FALSE;
    }
    pSataChannel = pAdapter->sataChannel[channelIndex];
    if (pSataChannel == NULL)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  channel data structu"
                 "re is not allocated\n", pAdapter->adapterId, channelIndex);
        return MV_FALSE;
    }

    mvOsSemTake(&pSataChannel->semaphore);
    if (pSataChannel->PMSupported == MV_FALSE)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  mvStorageDevPMReadReg"
                 " failed PM not supported for this channel\n",
                 pAdapter->adapterId, channelIndex);
        mvOsSemRelease( &pSataChannel->semaphore);
        return MV_FALSE;
    }
    if (pSataChannel->queueCommandsEnabled == MV_TRUE)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  mvStorageDevPMReadReg"
                 " command failed: EDMA is active\n",
                 pAdapter->adapterId, channelIndex);
        mvOsSemRelease( &pSataChannel->semaphore);
        return MV_FALSE;
    }

    result = _PMAccessReg(pAdapter, channelIndex, PMPort, PMReg, pValue,
                          registerStruct, MV_TRUE);

    mvOsSemRelease( &pSataChannel->semaphore);
    return result;
}



/*******************************************************************************
* mvPMDevWriteReg - Writes to port multiplier's internal register
*                  
*
* DESCRIPTION:
*       Performs PIO non-data command for writing to port multiplier's internal
*       register.
*
* INPUT:
*       pAdapter            - Pointer to the device data structure.
*       channelIndex        - Index of the required channel
*       PMPort              - This should be port 0xf
*       PMReg               - The required register to be read
*       value               - Holds 32bit of the value to be written
*       registerStruct      - A pointer to ATA register data structure. This
*                             holds the ATA registers dump after command
*                             is executed.
*
* RETURN:
*       MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
*       NONE
*
*******************************************************************************/
MV_BOOLEAN  mvPMDevWriteReg(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
                            MV_U8 PMPort, MV_U8 PMReg, MV_U32 value,
                            MV_STORAGE_DEVICE_REGISTERS *registerStruct)
{
    MV_SATA_CHANNEL *pSataChannel;
    MV_BOOLEAN      result;

    if (pAdapter == NULL)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "    :  mvStorageDevPMWriteReg"
                 " Failed, Bad adapter data structure pointer\n");
        return MV_FALSE;
    }
    pSataChannel = pAdapter->sataChannel[channelIndex];
    if (pSataChannel == NULL)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  channel data structu"
                 "re is not allocated\n", pAdapter->adapterId, channelIndex);
        return MV_FALSE;
    }

    mvOsSemTake(&pSataChannel->semaphore);
    if (pSataChannel->PMSupported == MV_FALSE)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  mvStorageDevPMWriteReg"
                 " failed PM not supported for this channel\n",
                 pAdapter->adapterId, channelIndex);
        mvOsSemRelease( &pSataChannel->semaphore);
        return MV_FALSE;
    }
    if (pSataChannel->queueCommandsEnabled == MV_TRUE)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  mvStorageDevPMWriteReg"
                 " command failed: EDMA is active\n",
                 pAdapter->adapterId, channelIndex);
        mvOsSemRelease( &pSataChannel->semaphore);
        return MV_FALSE;
    }

    result = _PMAccessReg(pAdapter, channelIndex, PMPort, PMReg, &value,
                          registerStruct, MV_FALSE);

    mvOsSemRelease( &pSataChannel->semaphore);
    return result;
}

static MV_BOOLEAN _checkPMPortSStatus(MV_SATA_ADAPTER* pAdapter, 
                                     MV_U8 channelIndex, 
                                     MV_U8 PMPort, 
                                     MV_BOOLEAN *error)
{
    MV_BOOLEAN result;
    MV_U32 SStatus;
    
    result = mvPMDevReadReg(pAdapter, channelIndex, PMPort,
                             MV_SATA_PSCR_SSTATUS_REG_NUM, &SStatus, NULL);    

    if (result == MV_FALSE)
    {
        *error = MV_TRUE;
        return result;
    }
    *error = MV_FALSE;
    SStatus &= (MV_BIT0 | MV_BIT1);
    if ((SStatus == (MV_BIT0 | MV_BIT1)) || (SStatus == 0))
    {
        return MV_TRUE;
    }
    else
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "[%d %d]"
                 "PM staggered spin-up - "
                 "SATA communication not established.\n",
                 pAdapter->adapterId, channelIndex);
        return MV_FALSE;
    }   

}


/*******************************************************************************
* mvPMDevEnableStaggeredSpinUp -
*                  
*
* DESCRIPTION:
*       Enables commnucation on a port multiplier's device SATA channel
*
* INPUT:
*       pAdapter            - Pointer to the device data structure.
*       channelIndex        - Index of the required channel
*       PMPort              - Required device SATA channel on port multiplier
*
* RETURN:
*       MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
*       NONE
*
*******************************************************************************/
MV_BOOLEAN  mvPMDevEnableStaggeredSpinUp(MV_SATA_ADAPTER *pAdapter,
                                         MV_U8 channelIndex, MV_U8 PMPort)
{
    MV_BOOLEAN  result;
    result = mvPMDevWriteReg(pAdapter, channelIndex, PMPort,
                             MV_SATA_PSCR_SCONTROL_REG_NUM, 0x311, NULL);
    if (result == MV_FALSE)
    {
        return result;
    }
    mvMicroSecondsDelay(pAdapter, MV_SATA_COMM_INIT_DELAY);
    result = mvPMDevWriteReg(pAdapter, channelIndex, PMPort,
                             MV_SATA_PSCR_SCONTROL_REG_NUM, 0x310, NULL);    
    return result;
}


/*******************************************************************************
* mvPMDevEnableStaggeredSpinUpAll -
*                  
*
* DESCRIPTION:
*       Enables commnucation on all port multiplier's device SATA channels
*
* INPUT:
*       pAdapter            - Pointer to the device data structure.
*       channelIndex        - Index of the required channel
*       PMNumOfPorts        - Number of device SATA channel the port multiplier
*                             has.
*       bitmask             - A pointer to 16bit data container that holds
*                             a bitmask of '1' when the relevant port multiplier's
*                             device port staggered spinup operation is success.
*
* RETURN:
*       MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
*       NONE
*
*******************************************************************************/

MV_BOOLEAN mvPMDevEnableStaggeredSpinUpAll(MV_SATA_ADAPTER *pSataAdapter,
                                           MV_U8 channelIndex,
                                           MV_U8 PMNumOfPorts,
                                           MV_U16 *bitmask)
{
    MV_U8 PMPort;
    MV_U8 retryCount;
    MV_U8 tmpBitmask = 1;
    if (bitmask == NULL)
    {
        return MV_FALSE;
    }
    /*Do not issue staggered spinup for port 0 - already done because of
    legacy port mode*/
    *bitmask = 1;
    for (PMPort = 1; PMPort < PMNumOfPorts; PMPort++)
    {

        if (mvPMDevEnableStaggeredSpinUp(pSataAdapter,                                           
                                         channelIndex, 
                                         PMPort) == MV_TRUE)
        {
            tmpBitmask |= (1 << PMPort);
        }
        else
        {
            mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, 
                     "Error [%d %d %d]: "
                     "PM enable staggered spin-up failed.\n",
                     pSataAdapter->adapterId, channelIndex, PMPort);
            return MV_FALSE;
        }
    }    
    mvMicroSecondsDelay(pSataAdapter, MV_SATA_COMM_INIT_WAIT_DELAY);    
    for (retryCount = 0; retryCount < 200; retryCount++)
    {   
        for (PMPort = 0; PMPort < PMNumOfPorts; PMPort++)
        {           
            MV_BOOLEAN error;
            if ((*bitmask) & (1 << PMPort))
            {
                continue;
            }
            if (_checkPMPortSStatus(pSataAdapter, 
                                    channelIndex, PMPort, &error) == MV_FALSE)
            {
                if (error == MV_TRUE)
                {
                    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, 
                             "[%d %d %d]: "
                             "Fatal error - cannot read PM port SStatus.\n",
                             pSataAdapter->adapterId, channelIndex, PMPort);
                    break;
                }
                mvMicroSecondsDelay(pSataAdapter, 1000);
            }
            else
            {
                if (bitmask != NULL)
                {
                    *bitmask |= (1 << PMPort);
                }
                mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, 
                         "[%d %d %d] PM SATA PHY ready after %d msec\n",
                         pSataAdapter->adapterId, channelIndex, 
                         PMPort, retryCount);           
            }
        }
        if (tmpBitmask == *bitmask)
        {
            break;
        }
    }
    if (tmpBitmask != *bitmask)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -