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

📄 mvstoragedev.c

📁 此为marvell6081芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            enableStorageDevInterrupt(pSataChannel);
            return MV_FALSE;
        }
        enableStorageDevInterrupt(pSataChannel);
        return MV_TRUE;
    }
    /* Wait for the command to complete */
    if (waitWhileStorageDevIsBusy(pAdapter, ioBaseAddr, eDmaRegsOffset, 3100, 10000) ==
        MV_FALSE)
    {
        enableStorageDevInterrupt(pSataChannel);
        return MV_FALSE;
    }
    /* Check the status register on DATA request commands */
    ATAstatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                 MV_ATA_DEVICE_STATUS_REG_OFFSET);
    if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_I)
    {
        if (!(ATAstatus & MV_ATA_DATA_REQUEST_STATUS))
        {
            mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: DRQ bit in ATA STATUS"
                     " register is not set\n", pAdapter->adapterId, channelIndex);
            enableStorageDevInterrupt(pSataChannel);
            return MV_FALSE;
        }
    }
    if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_II)
    {

        if (waitForDRQ(pAdapter, ioBaseAddr, eDmaRegsOffset, 500, 10000) 
            == MV_FALSE)
        {
            mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: DRQ bit in ATA STATUS"
                     " register is not set\n", pAdapter->adapterId, channelIndex);
            enableStorageDevInterrupt(pSataChannel);
            return MV_FALSE;
        }
    }
    for (i = 0; i < count; i++)
    {
        /* Every 256 loops (one sector has been transfered) we have to check the
           BUSY bit to verify that the Disk is ready for next block transfer  */
        if ((i & 0xff) == 0)
        {
            if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_II)
            {
                /* Perform a dummy read */
                MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                 MV_ATA_DEVICE_STATUS_REG_OFFSET);
                mvMicroSecondsDelay (pAdapter, 1);
            }
            if (waitWhileStorageDevIsBusy(pAdapter, 
                                          ioBaseAddr, eDmaRegsOffset, 
                                          50000, 100) == MV_FALSE)
            {
                enableStorageDevInterrupt(pSataChannel);
                return MV_FALSE;
            }
            if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_II)
            {
                if (waitForDRQ(pAdapter, ioBaseAddr, eDmaRegsOffset, 50000, 100) 
                    == MV_FALSE)
                {
                    enableStorageDevInterrupt(pSataChannel);
                    return MV_FALSE;
                }
            }
        }
        if (protocolType == MV_NON_UDMA_PROTOCOL_PIO_DATA_IN)
        {
            bufPtr[i] = MV_REG_READ_WORD(ioBaseAddr, eDmaRegsOffset +
                                         MV_ATA_DEVICE_PIO_DATA_REG_OFFSET);
        }
        else
        {
            MV_REG_WRITE_WORD(ioBaseAddr, eDmaRegsOffset +
                              MV_ATA_DEVICE_PIO_DATA_REG_OFFSET, bufPtr[i]);  
            MV_CPU_WRITE_BUFFER_FLUSH();
        }
    }


    /* Wait for the storage device to be available */
    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, " %d %d: on non-UDMA sequence - checking if"
             " device is has finished the command\n",
             pAdapter->adapterId, channelIndex);

    if (waitWhileStorageDevIsBusy(pAdapter, 
                                  ioBaseAddr, eDmaRegsOffset, 50000, 100) ==
        MV_FALSE)
    {
        enableStorageDevInterrupt(pSataChannel);
        return MV_FALSE;
    }

    if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_II)
    {

        if (waitForDRQToClear(pAdapter, ioBaseAddr, eDmaRegsOffset, 50000, 1) 
            == MV_FALSE)
        {
            enableStorageDevInterrupt(pSataChannel);
            return MV_FALSE;
        }
    }

    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, " %d %d: Finish NonUdma Command. Status=0x%02x"
             "\n", pAdapter->adapterId, channelIndex, 
             MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset + 
                              MV_ATA_DEVICE_STATUS_REG_OFFSET));
    enableStorageDevInterrupt(pSataChannel);
    return MV_TRUE;
}
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 result;

    if (isRead == MV_TRUE)
    {
        result = executeNonUDMACommand(pAdapter, channelIndex,
                                       MV_SATA_PM_CONTROL_PORT,
                                       MV_NON_UDMA_PROTOCOL_NON_DATA,
                                       MV_FALSE/*isEXT*/,
                                       NULL/*bufPtr*/,
                                       0/*count*/,
                                       PMReg /*features*/, 0/*sectorCount*/,
                                       0 /*lbaLow*/, 0 /*lbaMid*/, 0 /*lbaHigh*/,
                                       PMPort/*device*/,
                                       MV_ATA_COMMAND_PM_READ_REG/*command*/);
        if (result == MV_TRUE)
        {
            MV_BUS_ADDR_T   ioBaseAddr = pAdapter->adapterIoBaseAddress;
            MV_U32 eDmaRegsOffset = pAdapter->sataChannel[channelIndex]->eDmaRegsOffset;

            *pValue = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                       MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET);
            *pValue |= MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                        MV_ATA_DEVICE_LBA_LOW_REG_OFFSET) << 8;
            *pValue |= MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                        MV_ATA_DEVICE_LBA_MID_REG_OFFSET) << 16;
            *pValue |= MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                        MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET) << 24;
        }
    }
    else
    {
        result = executeNonUDMACommand(pAdapter, channelIndex, 
                                       MV_SATA_PM_CONTROL_PORT,
                                       MV_NON_UDMA_PROTOCOL_NON_DATA,
                                       MV_FALSE/*isEXT*/,
                                       NULL/*bufPtr*/,
                                       0/*count*/,
                                       PMReg /*features*/,
                                       (MV_U16)((*pValue) & 0xff)/*sectorCount*/,
                                       (MV_U16)(((*pValue) & 0xff00) >> 8) /*lbaLow*/,
                                       (MV_U16)(((*pValue) & 0xff0000) >> 16)   /*lbaMid*/,
                                       (MV_U16)(((*pValue) & 0xff000000) >> 24) /*lbaHigh*/,
                                       PMPort/*device*/,
                                       MV_ATA_COMMAND_PM_WRITE_REG/*command*/);
    }   
    if (registerStruct)
    {
        dumpAtaDeviceRegisters(pAdapter, channelIndex, MV_FALSE,
                               registerStruct);
    }
    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG|MV_DEBUG_PM, " %d %d: %s PM Reg %s: PM Port %x"
             ", PM Reg %d, value %x\n", pAdapter->adapterId, channelIndex,
             (isRead == MV_TRUE) ? "Read" : "Write", 
             (result == MV_TRUE) ? "Succeeded" : "Failed",
             PMPort, PMReg, *pValue);

    return result;
}

MV_BOOLEAN waitForDRQToClear(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;
}

void dumpAtaDeviceRegisters(MV_SATA_ADAPTER *pAdapter,
                            MV_U8 channelIndex, MV_BOOLEAN isEXT,
                            MV_STORAGE_DEVICE_REGISTERS *pRegisters)
{
    MV_BUS_ADDR_T   ioBaseAddr = pAdapter->adapterIoBaseAddress;
    MV_U32 eDmaRegsOffset = pAdapter->sataChannel[channelIndex]->eDmaRegsOffset;

    MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset + 
                      MV_ATA_DEVICE_CONTROL_REG_OFFSET, 0);

    pRegisters->errorRegister = 
    MV_REG_READ_BYTE(ioBaseAddr,
                     eDmaRegsOffset + MV_ATA_DEVICE_ERROR_REG_OFFSET);

    pRegisters->sectorCountRegister = 
    MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset + 
                     MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET) & 0x00ff;
    pRegisters->lbaLowRegister = 
    MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset + 
                     MV_ATA_DEVICE_LBA_LOW_REG_OFFSET) & 0x00ff;

    pRegisters->lbaMidRegister = 
    MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset + 
                     MV_ATA_DEVICE_LBA_MID_REG_OFFSET) & 0x00ff;

    pRegisters->lbaHighRegister = 
    MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset + 
                     MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET) & 0x00ff;

    if (isEXT == MV_TRUE)
    {
        /*set the HOB bit of DEVICE CONTROL REGISTER */

        MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset + 
                          MV_ATA_DEVICE_CONTROL_REG_OFFSET, MV_BIT7);

        pRegisters->sectorCountRegister |= (MV_REG_READ_BYTE(ioBaseAddr, 
                                                             eDmaRegsOffset + 
                                                             MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET) << 8) & 0xff00;

        pRegisters->lbaLowRegister |= (MV_REG_READ_BYTE(ioBaseAddr,
                                                        eDmaRegsOffset + MV_ATA_DEVICE_LBA_LOW_REG_OFFSET) << 8) 
                                      & 0xff00;

        pRegisters->lbaMidRegister |= (MV_REG_READ_BYTE(ioBaseAddr,
                                                        eDmaRegsOffset + MV_ATA_DEVICE_LBA_MID_REG_OFFSET) << 8) 
                                      & 0xff00;

        pRegisters->lbaHighRegister |= (MV_REG_READ_BYTE(ioBaseAddr,
                                                         eDmaRegsOffset + MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET) << 8) 
                                       & 0xff00;
        MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset + 
                          MV_ATA_DEVICE_CONTROL_REG_OFFSET, 0);

    }

    pRegisters->deviceRegister = MV_REG_READ_BYTE(ioBaseAddr, 
                                                  eDmaRegsOffset + MV_ATA_DEVICE_HEAD_REG_OFFSET);

    pRegisters->statusRegister = MV_REG_READ_BYTE(ioBaseAddr, 
                                                  eDmaRegsOffset + MV_ATA_DEVICE_STATUS_REG_OFFSET);


}


MV_BOOLEAN _doSoftReset(MV_SATA_CHANNEL *pSataChannel)
{
    MV_BUS_ADDR_T   ioBaseAddr = pSataChannel->mvSataAdapter->adapterIoBaseAddress;
    MV_U32          i;
    MV_U8           ATAstatus;
    MV_U32          eDmaRegsOffset = pSataChannel->eDmaRegsOffset;

    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_NON_UDMA_COMMAND | MV_DEBUG, "Issue SRST COMMAND\n");

/* Write to the Device Control register, bits 1,2:                      */ 
/* - bit 1 (nIEN): is the enable bit for the device assertion of INTRQ  */
/*   to the host. When the nIEN bit is set to one, or the device is not */
/*   selected, the device shall release the INTRQ signal.               */
/* - bit 2 (SRST): is the host software reset bit.                      */
    MV_REG_WRITE_BYTE(ioBaseAddr, pSataChannel->eDmaRegsOffset +
                      MV_ATA_DEVICE_CONTROL_REG_OFFSET, MV_BIT2|MV_BIT1); 
    MV_REG_READ_BYTE(ioBaseAddr, pSataChannel->eDmaRegsOffset +
                     MV_ATA_DEVICE_CONTROL_REG_OFFSET); 
    mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 10);

/* enableStorageDevInterrupt will clear the SRST bit*/
    enableStorageDevInterrupt(pSataChannel);

    mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 500);
    mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 500);
    mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 500);
    mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 500);

    for (i = 0;i < 31000; i++)
    {
        ATAstatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
                                     MV_ATA_DEVICE_STATUS_REG_OFFSET);
        if ((ATAstatus & MV_ATA_BUSY_STATUS) == 0)
        {
            return MV_TRUE;
        }
        mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 1000);
    }
    mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: Software reset failed "
             "Status=0x%02x\n", pSataChannel->mvSataAdapter->adapterId,
             pSataChannel->channelNumber, ATAstatus); 

    return MV_FALSE;

⌨️ 快捷键说明

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