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

📄 mvstoragedev.c

📁 此为marvell6081芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************
*
*                   Copyright 2003,MARVELL SEMICONDUCTOR ISRAEL, LTD.
* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.
* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT
* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE
* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.
* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,
* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.
*
* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES,
* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL
* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.
* (MJKK), MARVELL SEMICONDUCTOR ISRAEL. (MSIL),  MARVELL TAIWAN, LTD. AND
* SYSKONNECT GMBH.
********************************************************************************
* mvStorageDev.c - C File for implementation of the core driver.
*
* DESCRIPTION:
*       None.
*
* DEPENDENCIES:
*   mvOs.h
*   mvSata.h.   
*   mvStorageDev.h
*   mvRegs.h
*
* FILE REVISION NUMBER:
*       $Revision: 1.12 $
*******************************************************************************/
#include "mvOs.h"
#include "mvSata.h"
#include "mvStorageDev.h"
#include "mvRegs.h"

/* Defines */

/* functions for internal driver use */
MV_BOOLEAN waitWhileStorageDevIsBusy(MV_SATA_ADAPTER* pAdapter,
                                     MV_BUS_ADDR_T ioBaseAddr, 
                                     MV_U32 eDmaRegsOffset, MV_U32 loops,
                                     MV_U32 delay);
MV_BOOLEAN waitForDRQToClear(MV_SATA_ADAPTER* pAdapter,
                             MV_BUS_ADDR_T ioBaseAddr, 
                             MV_U32 eDmaRegsOffset, MV_U32 loops,
                             MV_U32 delay);

void enableStorageDevInterrupt (MV_SATA_CHANNEL *pSataChannel);
void disableStorageDevInterrupt(MV_SATA_CHANNEL *pSataChannel);
static MV_BOOLEAN isStorageDevReadyForPIO(MV_SATA_CHANNEL *pSataChannel);
void dumpAtaDeviceRegisters(MV_SATA_ADAPTER *pAdapter,
                            MV_U8 channelIndex, MV_BOOLEAN isEXT,
                            MV_STORAGE_DEVICE_REGISTERS *pRegisters);
MV_BOOLEAN _doSoftReset(MV_SATA_CHANNEL *pSataChannel);
extern void _setActivePMPort(MV_SATA_CHANNEL *pSataChannel, MV_U8 PMPort);
extern void disableSaDevInterrutps(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex);

MV_BOOLEAN  _PMAccessReg(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
                         MV_U8 PMPort, MV_U8 PMReg, MV_U32 *pValue,
                         MV_STORAGE_DEVICE_REGISTERS *registerStruct,
                         MV_BOOLEAN isRead);

MV_BOOLEAN executeNonUDMACommand(MV_SATA_ADAPTER *pAdapter,
                                 MV_U8 channelIndex,
                                 MV_U8  PMPort,
                                 MV_NON_UDMA_PROTOCOL protocolType,
                                 MV_BOOLEAN  isEXT,
                                 MV_U16_PTR bufPtr, MV_U32 count,
                                 MV_U16 features, 
                                 MV_U16 sectorCount,
                                 MV_U16 lbaLow, MV_U16 lbaMid,
                                 MV_U16 lbaHigh, MV_U8 device,
                                 MV_U8 command);

/*******************************************************************************
* waitWhileStorageDevIsBusy - Wait for the storage device to be released from 
*                             busy state.
*
* DESCRIPTION:
*   The busy bit is set to one to indicate that the storage device is busy. The
*   busy bit shall be set to one by the device only when one of the following 
*   events occurs:
*
*   1) after either the negation of RESET- or the setting of the SRST bit to one
*      in the Device Control register.
*   2) after writing the Command register if the DRQ bit is not set to one.
*   3) between blocks of a data transfer during PIO data-in commands before the
*      DRQ bit is cleared to zero. 
*   4) after the transfer of a data block during PIO data-out commands before 
*      the DRQ bit is cleared to zero.
*   5) during the data transfer of DMA commands either the BSY bit, the DRQ bit,
*      or both shall be set to one.
*   6) after the command packet is received during the execution of a PACKET 
*      command.
*
* INPUT:
*     ioBaseAddr     - The PCI I/O window base address of the adapter.
*     eDmaRegsOffset - The EDMA register's offset of the relevant SATA channel. 
*     loops          - max number of times to pool the status register.
*     delay          - number of u seconds to wait each loop.
*
* RETURN:
*     MV_TRUE if the device is released from busy state, MV_FALSE otherwise.
* COMMENTS:
*     None.
*
*******************************************************************************/
MV_BOOLEAN waitWhileStorageDevIsBusy(MV_SATA_ADAPTER* pAdapter,
                                     MV_BUS_ADDR_T ioBaseAddr, 
                                     MV_U32 eDmaRegsOffset, MV_U32 loops,
                                     MV_U32 delay)
{
    MV_U8   ATAstatus = 0;
    MV_U32  i;

    for (i = 0;i < loops; i++)
    {
        ATAstatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                     MV_ATA_DEVICE_STATUS_REG_OFFSET);
        if ((ATAstatus & MV_ATA_BUSY_STATUS) == 0)
        {

            if ((ATAstatus & MV_ATA_ERROR_STATUS) == 0)
            {
                mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, "waitWhileStorageDevIsBusy: %d loops *" 
                         "%d usecs\n", i, delay);
                return MV_TRUE;
            }
            else
            {
                mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "waitWhileStorageDevIsBusy<FAILED>: Device ERROR"
                         " Status: 0x%02x\n", ATAstatus);
                return MV_FALSE;
            }
        }
        mvMicroSecondsDelay(pAdapter, delay);
    }
    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "waitWhileStorageDevIsBusy<FAILED>: Time out - Device ERROR"
             " Status: 0x%02x. loops %d, delay %d\n", ATAstatus, loops, delay);

    return MV_FALSE;
}


MV_BOOLEAN waitForDRQ(MV_SATA_ADAPTER* pAdapter,
                      MV_BUS_ADDR_T ioBaseAddr, 
                      MV_U32 eDmaRegsOffset, MV_U32 loops,
                      MV_U32 delay)
{
    MV_U8   ATAstatus = 0;
    MV_U32  i;

    for (i = 0;i < loops; i++)
    {
        ATAstatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                     MV_ATA_DEVICE_STATUS_REG_OFFSET);
        if ((ATAstatus & MV_ATA_BUSY_STATUS) == 0)
        {
            if (ATAstatus & MV_ATA_DATA_REQUEST_STATUS)
            {
                mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, "waitWhileStorageDevIsBusy: %d loops *" 
                         "%d usecs\n", i, delay);
                return MV_TRUE;
            }
        }
        mvMicroSecondsDelay(pAdapter, delay);
    }
    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "waitWhileStorageDevIsBusy<FAILED>: Time out - Device ERROR"
             " Status: 0x%02x. loops %d, delay %d\n", ATAstatus, loops, delay);

    return MV_FALSE;
}
/*******************************************************************************
* enableStorageDevInterrupt - Enable the storage device to be able to issue 
*                       interrupt.
*
* DESCRIPTION:
*   Enable the connected storage device to the given channel to assert INTRQ by
*   clearing nIEN bit in the Device Control register.
*
* INPUT:
*   pSataChannel - Pointer to the Sata channel data structure.   
*
* RETURN:
*   None.
*
* COMMENTS:
*   this function also clears the SRST bit in the Device Control register.
*
*******************************************************************************/
void enableStorageDevInterrupt(MV_SATA_CHANNEL *pSataChannel)
{

    MV_REG_WRITE_BYTE(pSataChannel->mvSataAdapter->adapterIoBaseAddress,
                      pSataChannel->eDmaRegsOffset +
                      MV_ATA_DEVICE_CONTROL_REG_OFFSET,0);
    MV_REG_READ_BYTE(pSataChannel->mvSataAdapter->adapterIoBaseAddress,
                     pSataChannel->eDmaRegsOffset +
                     MV_ATA_DEVICE_CONTROL_REG_OFFSET);
}

/*******************************************************************************
* disableStorageDevInterrupt - Disable the storage device to be able to issue 
*                              interrupt.
*
* DESCRIPTION:
*   This function disable the connected storage device to the given channel to 
*   assert INTRQ by setting nIEN bit in the Device Control register.
*
* INPUT:
*   pSataChannel - Pointer to the Sata channel data structure.   
*
* RETURN:
*   None.
*
* COMMENTS:
*   this function also clears the SRST bit
*
*******************************************************************************/
void disableStorageDevInterrupt(MV_SATA_CHANNEL *pSataChannel)
{


    MV_REG_WRITE_BYTE(pSataChannel->mvSataAdapter->adapterIoBaseAddress,
                      pSataChannel->eDmaRegsOffset +
                      MV_ATA_DEVICE_CONTROL_REG_OFFSET, MV_BIT1);
    MV_REG_READ_BYTE(pSataChannel->mvSataAdapter->adapterIoBaseAddress,
                     pSataChannel->eDmaRegsOffset +
                     MV_ATA_DEVICE_STATUS_REG_OFFSET);
}

/*******************************************************************************
* isStorageDevReadyForPIO - Check that the storage device connected to the given
*                           channel and the channel itself are ready to perform 
*                           PIO commands.
*
* DESCRIPTION:  
*   Check if the device connected to the given channel and the channel itself 
*   are ready for PIO commands.
*
* INPUT:
*       pSataChannel - Pointer to the SATA channel data structure.
*
* RETURN:
*       MV_TRUE if the channel and the connected device ready to do PIO,
*       MV_FALSE otherwise.
*
* COMMENTS:
*     If the adapter's eEnEDMA bit in the EDMA Command Register is set, PIO
*     commands cannot be issued. The eEnEDMA bit cannot be reset by the CPU. 
*     Only the EDMA resets it, when bit eDsEDMA is set or when an error 
*     condition occurs. 
*
*******************************************************************************/
static MV_BOOLEAN isStorageDevReadyForPIO(MV_SATA_CHANNEL *pSataChannel)
{
    MV_BUS_ADDR_T ioBaseAddr =pSataChannel->mvSataAdapter->adapterIoBaseAddress;
    MV_U32  eDmaRegsOffset = pSataChannel->eDmaRegsOffset;
    MV_U8   ATAcontrolRegValue;

    /* If the adapter's eEnEDMA bit in the EDMA Command Register is set  */
    /* PIO commands cannot be issued.                                       */
    if (pSataChannel->queueCommandsEnabled == MV_TRUE)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: PIO command failed:"
                 "EDMA is active\n", pSataChannel->mvSataAdapter->adapterId,
                 pSataChannel->channelNumber);
        return MV_FALSE;
    }
    /* Check if BUSY bit is '0' */

    /* Reading the Control register actually gives us the Alternate Status  */
    /* register content (ATA protocol). If the busy bit is set in the       */
    /* Alternate Status register, we wait for 50 mili-sec and try again, if */
    /* the busy bit is still set, we return false indicating that the       */
    /* device is not ready for PIO commands.                                */
    ATAcontrolRegValue = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                          MV_ATA_DEVICE_CONTROL_REG_OFFSET);
    if ((ATAcontrolRegValue & MV_ATA_BUSY_STATUS)!= 0)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  control regiser is "
                 "0x%02x\n",pSataChannel->mvSataAdapter->adapterId,
                 pSataChannel->channelNumber,ATAcontrolRegValue);
        return MV_FALSE;
    }
    if ((ATAcontrolRegValue & MV_ATA_READY_STATUS) != 
        MV_ATA_READY_STATUS)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  storage drive is not"
                 " ready, ATA STATUS=0x%02x\n",
                 pSataChannel->mvSataAdapter->adapterId,
                 pSataChannel->channelNumber, ATAcontrolRegValue);
        return MV_FALSE;
    }
    /* The device is ready for PIO commands */
    return MV_TRUE;
}

MV_BOOLEAN mvStorageDevATAIdleImmediate(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex)
{
    MV_SATA_CHANNEL *pSataChannel;
    MV_BUS_ADDR_T ioBaseAddr;
    MV_U32  eDmaRegsOffset;

    if (pAdapter == NULL)
    {
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "    :  mvStorageDevATAIdentif"
                 "yDevice failed, Bad adapter data structure pointer\n");
        return MV_FALSE;
    }
    pSataChannel = pAdapter->sataChannel[channelIndex];
    if (pSataChannel == NULL)
    {     /* If the pointer do not exists, retrun false */
        mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d:  channel data "
                 "structure is not allocated\n", pAdapter->adapterId, 

⌨️ 快捷键说明

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