Esempio n. 1
0
static void rw16_taskfile(PMV_Request req, PATA_TaskFile tf, int tag)
{
	if (req->Cmd_Flag & CMD_FLAG_NCQ) {
		
		tf->Features = req->Cdb[13];
		tf->Feature_Exp = req->Cdb[12];

		tf->Sector_Count = tag<<3;
		
		tf->LBA_Low = req->Cdb[9];
		tf->LBA_Mid = req->Cdb[8];
		tf->LBA_High = req->Cdb[7];
		tf->LBA_Low_Exp = req->Cdb[6];
		tf->LBA_Mid_Exp = req->Cdb[5];
		tf->LBA_High_Exp = req->Cdb[4];

		tf->Device = MV_BIT(6);

		if (req->Cdb[0] == SCSI_CMD_READ_16)
			tf->Command = ATA_CMD_READ_FPDMA_QUEUED;
		else if (req->Cdb[0] == SCSI_CMD_WRITE_16)
			tf->Command = ATA_CMD_WRITE_FPDMA_QUEUED;
	} else if (req->Cmd_Flag & CMD_FLAG_48BIT) {
		MV_DASSERT(!(req->Cmd_Flag&CMD_FLAG_NCQ));

		tf->Sector_Count = req->Cdb[13];
		tf->Sector_Count_Exp = req->Cdb[12];

		tf->LBA_Low = req->Cdb[9];
		tf->LBA_Mid = req->Cdb[8];
		tf->LBA_High = req->Cdb[7];
		tf->LBA_Low_Exp = req->Cdb[6];
		tf->LBA_Mid_Exp = req->Cdb[5];
		tf->LBA_High_Exp = req->Cdb[4];

		tf->Device = MV_BIT(6);

		if (req->Cdb[0] == SCSI_CMD_READ_16)
			tf->Command = ATA_CMD_READ_DMA_EXT;
		else if (req->Cdb[0] == SCSI_CMD_WRITE_16)
			tf->Command = ATA_CMD_WRITE_DMA_EXT;
	}
}
MV_BOOLEAN ATAPI_CDB2TaskFile(
    IN PDomain_Device pDevice,
    IN PMV_Request pReq,
    OUT PATA_TaskFile pTaskFile
)
{
    MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile));

    /* At the same time, set the command category as well. */
    switch ( pReq->Cdb[0] )
    {
    case SCSI_CMD_MARVELL_SPECIFIC:
        /* This request should be for core module */
        if ( pReq->Cdb[1]!=CDB_CORE_MODULE )
            return MV_FALSE;

        switch ( pReq->Cdb[2] )
        {
        case CDB_CORE_IDENTIFY:
            pTaskFile->Command = ATA_CMD_IDENTIFY_ATAPI;
            break;

        case CDB_CORE_SET_UDMA_MODE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
            if ( pReq->Cdb[4]==MV_TRUE )
                pTaskFile->Sector_Count = 0x20 | pReq->Cdb[3];	/* MDMA mode */
            else
                pTaskFile->Sector_Count = 0x40 | pReq->Cdb[3];	/* UDMA mode*/

            //TBD: Check the 80-conductor cable in order to enable UDMA greater than 2.
            break;

        case CDB_CORE_SET_PIO_MODE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
            pTaskFile->Sector_Count = 0x08 | pReq->Cdb[3];
            break;

        default:
            return MV_FALSE;
        }
        break;
    case SCSI_CMD_READ_DISC_INFO: /* unimplemented SCSI cmds */
    /*	return MV_FALSE;   */
    case SCSI_CMD_READ_10:
    case SCSI_CMD_READ_12:
    case SCSI_CMD_WRITE_10:
    case SCSI_CMD_VERIFY_10:
    case SCSI_CMD_INQUIRY:
    case SCSI_CMD_READ_CAPACITY_10:
    case SCSI_CMD_TEST_UNIT_READY:
    case SCSI_CMD_MODE_SENSE_10:
    case SCSI_CMD_MODE_SELECT_10:
    case SCSI_CMD_PREVENT_MEDIUM_REMOVAL:
    case SCSI_CMD_READ_TOC:
    case SCSI_CMD_START_STOP_UNIT:
    case SCSI_CMD_SYNCHRONIZE_CACHE_10:
    case SCSI_CMD_REQUEST_SENSE:
    default:
        /*
         * Use packet command
         */
        /* Features: DMA, OVL, DMADIR */
#if defined(USE_DMA_FOR_ALL_PACKET_COMMAND)
        if ( !(pReq->Cmd_Flag&CMD_FLAG_NON_DATA) )
        {
            pTaskFile->Features |= MV_BIT(0);
        }
#else
        if ( pReq->Cmd_Flag&CMD_FLAG_DMA )
        {
            //if ( SCSI_IS_READ(pReq->Cdb[0]) || SCSI_IS_WRITE(pReq->Cdb[0]) )
            pTaskFile->Features |= MV_BIT(0);
            if ((pReq->Cdb[0] != SCSI_CMD_READ_10)
                    && (pReq->Cdb[0] != SCSI_CMD_READ_12)
                    && (pReq->Cdb[0] != SCSI_CMD_WRITE_10))
                MV_PRINT("[BERLIN A0]DMA transfer for prohibited command 0x%02x\n", pReq->Cdb[0]);
        }
#endif
        //TBD: OVL: overlapped.
        //TBD: DMADIR in IDENTIFY PACKET DEVICE word 62

        //TBD: Sector Count: Tag

        /* Byte count low and byte count high */
        if ( pReq->Data_Transfer_Length>0xFFFF )
        {
            pTaskFile->LBA_Mid = 0xFF;
            pTaskFile->LBA_High = 0xFF;
        }
        else
        {
            pTaskFile->LBA_Mid = (MV_U8)pReq->Data_Transfer_Length;
            pTaskFile->LBA_High = (MV_U8)(pReq->Data_Transfer_Length>>8);
        }

        pTaskFile->Command = ATA_CMD_PACKET;

        break;
    }

    return MV_TRUE;
}
MV_BOOLEAN ATA_CDB2TaskFile(
    IN PDomain_Device pDevice,
    IN PMV_Request pReq,
    IN MV_U8 tag,
    OUT PATA_TaskFile pTaskFile
)
{
    MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile));

    switch ( pReq->Cdb[0] )
    {
    case SCSI_CMD_READ_10:
    case SCSI_CMD_WRITE_10:
    {

        /*
         * The OS maximum tranfer length is set to 128K.
         * For ATA_CMD_READ_DMA and ATA_CMD_WRITE_DMA,
         * the max size they can handle is 256 sectors.
         * And Sector_Count==0 means 256 sectors.
         * If OS request max lenght>128K, for 28 bit device, we have to split requests.
         */
        MV_DASSERT( ( (((MV_U16)pReq->Cdb[7])<<8) | (pReq->Cdb[8]) ) <= 256 );
#if 1
        {
            if ( ( (((MV_U16)pReq->Cdb[7])<<8) | (pReq->Cdb[8]) ) > MV_MAX_TRANSFER_SECTOR ) {
                printk("READ10/WRITE10 error: sector count 0x%xlimited.\n", (((MV_U16)pReq->Cdb[7])<<8) | (pReq->Cdb[8]));
            }
        }
#endif

        /*
         * 24 bit LBA can express 128GB.
         * 4 bytes LBA like SCSI_CMD_READ_10 can express 2TB.
         */

        /* Make sure Cmd_Flag has set already. */
        if ( pReq->Cmd_Flag&CMD_FLAG_NCQ )
        {
            //MV_DASSERT( pReq->Cmd_Flag&CMD_FLAG_48BIT );	//TBD: Do we need set 48bit for NCQ

            pTaskFile->Features = pReq->Cdb[8];
            pTaskFile->Feature_Exp = pReq->Cdb[7];

            pTaskFile->Sector_Count = tag<<3;

            pTaskFile->LBA_Low = pReq->Cdb[5];
            pTaskFile->LBA_Mid = pReq->Cdb[4];
            pTaskFile->LBA_High = pReq->Cdb[3];
            pTaskFile->LBA_Low_Exp = pReq->Cdb[2];

            pTaskFile->Device = MV_BIT(6);

            if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
                pTaskFile->Command = ATA_CMD_READ_FPDMA_QUEUED;
            else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
                pTaskFile->Command = ATA_CMD_WRITE_FPDMA_QUEUED;
        }
        else if ( pReq->Cmd_Flag&CMD_FLAG_48BIT )
        {
            MV_DASSERT( !(pReq->Cmd_Flag&CMD_FLAG_NCQ) );

            pTaskFile->Sector_Count = pReq->Cdb[8];
            pTaskFile->Sector_Count_Exp = pReq->Cdb[7];

            pTaskFile->LBA_Low = pReq->Cdb[5];
            pTaskFile->LBA_Mid = pReq->Cdb[4];
            pTaskFile->LBA_High = pReq->Cdb[3];
            pTaskFile->LBA_Low_Exp = pReq->Cdb[2];

            pTaskFile->Device = MV_BIT(6);

            if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
                pTaskFile->Command = ATA_CMD_READ_DMA_EXT;
            else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
                pTaskFile->Command = ATA_CMD_WRITE_DMA_EXT;
        }
        else
        {
            /* 28 bit DMA */
            pTaskFile->Sector_Count = pReq->Cdb[8];		/* Could be zero */

            pTaskFile->LBA_Low = pReq->Cdb[5];
            pTaskFile->LBA_Mid = pReq->Cdb[4];
            pTaskFile->LBA_High = pReq->Cdb[3];

            pTaskFile->Device = MV_BIT(6) | (pReq->Cdb[2]&0xF);

            MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );

            if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
                pTaskFile->Command = ATA_CMD_READ_DMA;
            else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
                pTaskFile->Command = ATA_CMD_WRITE_DMA;
        }

        break;
    }

    case SCSI_CMD_VERIFY_10:
        /*
         * For verify command, the size may need use two MV_U8, especially Windows.
         * For 28 bit device, we have to split the request.
         * For 48 bit device, we use ATA_CMD_VERIFY_EXT.
         */
        if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
        {
            pTaskFile->Sector_Count = pReq->Cdb[8];
            pTaskFile->Sector_Count_Exp = pReq->Cdb[7];

            pTaskFile->LBA_Low = pReq->Cdb[5];
            pTaskFile->LBA_Mid = pReq->Cdb[4];
            pTaskFile->LBA_High = pReq->Cdb[3];
            pTaskFile->LBA_Low_Exp = pReq->Cdb[2];

            pTaskFile->Device = MV_BIT(6);

            pTaskFile->Command = ATA_CMD_VERIFY_EXT;
        }
        else
        {
            //TBD: If the device doesn't support 48 bit LBA. We have to split this request.
            //ATA_CMD_VERIFY
            //MV_ASSERT(MV_FALSE);
            //Sorry here I didn't do the verify exact as the OS required.
            //It need effort to split request. Currently I just pretect I've fulfilled the request.
            pTaskFile->Sector_Count = pReq->Cdb[8];

            pTaskFile->LBA_Low = pReq->Cdb[5];
            pTaskFile->LBA_Mid = pReq->Cdb[4];
            pTaskFile->LBA_High = pReq->Cdb[3];

            pTaskFile->Device = MV_BIT(6) | (pReq->Cdb[2]&0xF);

            MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );

            pTaskFile->Command = ATA_CMD_VERIFY;
        }

        break;

    case SCSI_CMD_MARVELL_SPECIFIC:
    {
        /* This request should be for core module */
        if ( pReq->Cdb[1]!=CDB_CORE_MODULE )
            return MV_FALSE;
        switch ( pReq->Cdb[2] )
        {
        case CDB_CORE_IDENTIFY:
            pTaskFile->Command = ATA_CMD_IDENTIFY_ATA;
            break;

        case CDB_CORE_SET_UDMA_MODE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
            pTaskFile->Sector_Count = 0x40 | pReq->Cdb[3];
            MV_DASSERT( pReq->Cdb[4]==MV_FALSE );	/* Use UDMA mode */
            //TBD: Check the 80-conductor cable in order to enable UDMA greater than 2.
            break;

        case CDB_CORE_SET_PIO_MODE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
            pTaskFile->Sector_Count = 0x08 | pReq->Cdb[3];
            break;

        case CDB_CORE_ENABLE_WRITE_CACHE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_ENABLE_WRITE_CACHE;
            break;

        case CDB_CORE_DISABLE_WRITE_CACHE:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_DISABLE_WRITE_CACHE;
            break;

        case CDB_CORE_ENABLE_SMART:
            pTaskFile->Command = ATA_CMD_SMART;
            pTaskFile->Features = ATA_CMD_ENABLE_SMART;
            pTaskFile->LBA_Mid = 0x4F;
            pTaskFile->LBA_High = 0xC2;
            break;

        case CDB_CORE_DISABLE_SMART:
            pTaskFile->Command = ATA_CMD_SMART;
            pTaskFile->Features = ATA_CMD_DISABLE_SMART;
            pTaskFile->LBA_Mid = 0x4F;
            pTaskFile->LBA_High = 0xC2;
            break;

        case CDB_CORE_SMART_RETURN_STATUS:
            pTaskFile->Command = ATA_CMD_SMART;
            pTaskFile->Features = ATA_CMD_SMART_RETURN_STATUS;
            pTaskFile->LBA_Mid = 0x4F;
            pTaskFile->LBA_High = 0xC2;
            break;

        case CDB_CORE_SHUTDOWN:
            if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
                pTaskFile->Command = ATA_CMD_FLUSH_EXT;
            else
                pTaskFile->Command = ATA_CMD_FLUSH;
            break;

        case CDB_CORE_ENABLE_READ_AHEAD:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_ENABLE_READ_LOOK_AHEAD;
            break;

        case CDB_CORE_DISABLE_READ_AHEAD:
            pTaskFile->Command = ATA_CMD_SET_FEATURES;
            pTaskFile->Features = ATA_CMD_DISABLE_READ_LOOK_AHEAD;
            break;

        case CDB_CORE_READ_LOG_EXT:
            pTaskFile->Command = ATA_CMD_READ_LOG_EXT;
            pTaskFile->Sector_Count = 1;	/* Read one sector */
            pTaskFile->LBA_Low = 0x10;		/* Page 10h */
            break;

        default:
            return MV_FALSE;
        }
        break;
    }

    case SCSI_CMD_SYNCHRONIZE_CACHE_10:
        if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
            pTaskFile->Command = ATA_CMD_FLUSH_EXT;
        else
            pTaskFile->Command = ATA_CMD_FLUSH;
        pTaskFile->Device = MV_BIT(6);
        break;
    case SCSI_CMD_START_STOP_UNIT:
        if (pReq->Cdb[4] & MV_BIT(0))
        {
            pTaskFile->Command = ATA_CMD_SEEK;
            pTaskFile->Device = MV_BIT(6);
        }
        else
        {
            pTaskFile->Command = ATA_CMD_STANDBY_IMMEDIATE;
        }
        break;

    case SCSI_CMD_REQUEST_SENSE:
    case SCSI_CMD_MODE_SELECT_10:
    case SCSI_CMD_MODE_SENSE_10:
    default:
        MV_PRINT("[Galois]ATA_CDB2TaskFile error: Unknown request: 0x%x.\n", pReq->Cdb[0]);
        return MV_FALSE;
    }

    return MV_TRUE;
}
Esempio n. 4
0
MV_BOOLEAN ATAPI_CDB2TaskFile(
	IN PDomain_Device pDevice,
	IN PMV_Request pReq, 
	OUT PATA_TaskFile pTaskFile
	)
{
	MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile));

	/* At the same time, set the command category as well. */
	switch ( pReq->Cdb[0] )
	{
	case SCSI_CMD_MARVELL_SPECIFIC:
		/* This request should be for core module */
		if ( pReq->Cdb[1]!=CDB_CORE_MODULE )
			return MV_FALSE;

		switch ( pReq->Cdb[2] )
		{
		case CDB_CORE_IDENTIFY:
			pTaskFile->Command = ATA_CMD_IDENTIY_ATAPI;
			break;
					
		case CDB_CORE_SET_UDMA_MODE:
			pTaskFile->Command = ATA_CMD_SET_FEATURES;
			pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
			if ( pReq->Cdb[4]==MV_TRUE )
				pTaskFile->Sector_Count = 0x20 | pReq->Cdb[3];	/* MDMA mode */
			else
				pTaskFile->Sector_Count = 0x40 | pReq->Cdb[3];	/* UDMA mode*/

			break;
					
		case CDB_CORE_SET_PIO_MODE:
			pTaskFile->Command = ATA_CMD_SET_FEATURES;
			pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
			pTaskFile->Sector_Count = 0x08 | pReq->Cdb[3];
			break;

		case CDB_CORE_OS_SMART_CMD:
		//Now we don't support SMART on ATAPI device.
		default:
			return MV_FALSE;
		}
		break;

#ifdef _OS_LINUX
	case SCSI_CMD_READ_DISC_INFO:
#endif /* _OS_LINUX */
	case SCSI_CMD_READ_10:
	case SCSI_CMD_WRITE_10:
	case SCSI_CMD_VERIFY_10:
	case SCSI_CMD_INQUIRY:
	case SCSI_CMD_READ_CAPACITY_10:
	case SCSI_CMD_TEST_UNIT_READY:
	case SCSI_CMD_MODE_SENSE_10:
	case SCSI_CMD_MODE_SELECT_10:
	case SCSI_CMD_PREVENT_MEDIUM_REMOVAL:
	case SCSI_CMD_READ_TOC:
	case SCSI_CMD_START_STOP_UNIT:
	case SCSI_CMD_SYNCHRONIZE_CACHE_10:
	case SCSI_CMD_REQUEST_SENSE:
	default:
		/* 
		 * Use packet command 
		 */
		/* Features: DMA, OVL, DMADIR */
#if defined(USE_DMA_FOR_ALL_PACKET_COMMAND)
		if ( !(pReq->Cmd_Flag&CMD_FLAG_NON_DATA) )
		{
			pTaskFile->Features |= MV_BIT(0);
		}
#elif defined(USE_PIO_FOR_ALL_PACKET_COMMAND)
		/* do nothing */
#else
		if ( pReq->Cmd_Flag&CMD_FLAG_DMA )
			pTaskFile->Features |= MV_BIT(0);
#endif
		/* Byte count low and byte count high */
		if ( pReq->Data_Transfer_Length>0xFFFF )
		{
			pTaskFile->LBA_Mid = 0xFF;
			pTaskFile->LBA_High = 0xFF;
		}
		else
		{
			pTaskFile->LBA_Mid = (MV_U8)pReq->Data_Transfer_Length;
			pTaskFile->LBA_High = (MV_U8)(pReq->Data_Transfer_Length>>8);
		}

		pTaskFile->Command = ATA_CMD_PACKET;

		break;
	}

	/* 
	 * Attention: Never return before this line if your return is MV_TRUE.
	 * We need set the slave DEV bit here. 
	 */
	if ( pDevice->Is_Slave )		
		pTaskFile->Device |= MV_BIT(4);

	return MV_TRUE;
}
Esempio n. 5
0
MV_BOOLEAN ATA_CDB2TaskFile(
	IN PDomain_Device pDevice,
	IN PMV_Request pReq, 
	IN MV_U8 tag,
	OUT PATA_TaskFile pTaskFile
	)
{
	MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile));

	switch ( pReq->Cdb[0] )
	{
		case SCSI_CMD_READ_10:
		case SCSI_CMD_WRITE_10:
			{
				
				/* 
				 * The OS maximum tranfer length is set to 128K.
				 * For ATA_CMD_READ_DMA and ATA_CMD_WRITE_DMA,
				 * the max size they can handle is 256 sectors.
				 * And Sector_Count==0 means 256 sectors.
				 * If OS request max lenght>128K, for 28 bit device, we have to split requests.
				 */
#ifndef _OS_LINUX  //Avoid keneral panic 
				MV_DASSERT( ( (((MV_U16)pReq->Cdb[7])<<8) | (pReq->Cdb[8]) ) <= 256 );
#endif
				/*
				 * 24 bit LBA can express 128GB.
				 * 4 bytes LBA like SCSI_CMD_READ_10 can express 2TB.
				 */
			
				/* Make sure Cmd_Flag has set already. */
				#ifdef SUPPORT_ATA_SECURITY_CMD
				if ( pReq->Cmd_Flag&CMD_FLAG_NCQ && !((pDevice->Setting&DEVICE_SETTING_SECURITY_LOCKED)==0x10))
				#else
				if ( pReq->Cmd_Flag&CMD_FLAG_NCQ)
				#endif
				{
					
					pTaskFile->Features = pReq->Cdb[8];
					pTaskFile->Feature_Exp = pReq->Cdb[7];

					pTaskFile->Sector_Count = tag<<3;
					
					pTaskFile->LBA_Low = pReq->Cdb[5];
					pTaskFile->LBA_Mid = pReq->Cdb[4];
					pTaskFile->LBA_High = pReq->Cdb[3];
					pTaskFile->LBA_Low_Exp = pReq->Cdb[2];
		
					pTaskFile->Device = MV_BIT(6);

					if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
						pTaskFile->Command = ATA_CMD_READ_FPDMA_QUEUED;
					else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
						pTaskFile->Command = ATA_CMD_WRITE_FPDMA_QUEUED;
				}
				else if ( pReq->Cmd_Flag&CMD_FLAG_48BIT )
				{
					MV_DASSERT( !(pReq->Cmd_Flag&CMD_FLAG_NCQ) );

					pTaskFile->Sector_Count = pReq->Cdb[8];
					pTaskFile->Sector_Count_Exp = pReq->Cdb[7];

					pTaskFile->LBA_Low = pReq->Cdb[5];
					pTaskFile->LBA_Mid = pReq->Cdb[4];
					pTaskFile->LBA_High = pReq->Cdb[3];
					pTaskFile->LBA_Low_Exp = pReq->Cdb[2];

					pTaskFile->Device = MV_BIT(6);

					if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
						pTaskFile->Command = ATA_CMD_READ_DMA_EXT;
					else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
						pTaskFile->Command = ATA_CMD_WRITE_DMA_EXT;
				}
				else
				{
					/* 28 bit DMA */
					pTaskFile->Sector_Count = pReq->Cdb[8];		/* Could be zero */
	
					pTaskFile->LBA_Low = pReq->Cdb[5];
					pTaskFile->LBA_Mid = pReq->Cdb[4];
					pTaskFile->LBA_High = pReq->Cdb[3];
			
					pTaskFile->Device = MV_BIT(6) | (pReq->Cdb[2]&0xF);
					
					MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );

					if ( pReq->Cdb[0]==SCSI_CMD_READ_10 )
						pTaskFile->Command = ATA_CMD_READ_DMA;
					else if ( pReq->Cdb[0]==SCSI_CMD_WRITE_10 )
						pTaskFile->Command = ATA_CMD_WRITE_DMA;
				}

				break;
			}
#ifdef SUPPORT_ATA_SECURITY_CMD
		case ATA_16:
			scsi_ata_passthru_16_fill_taskfile(pReq,pTaskFile);
			break;
#endif
		case SCSI_CMD_READ_16:
		case SCSI_CMD_WRITE_16:
			rw16_taskfile(pReq, pTaskFile, tag);
			break;

		case SCSI_CMD_VERIFY_10:
			/* 
			 * For verify command, the size may need use two MV_U8, especially Windows.
			 * For 28 bit device, we have to split the request.
			 * For 48 bit device, we use ATA_CMD_VERIFY_EXT.
			 */
			if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
			{
				pTaskFile->Sector_Count = pReq->Cdb[8];
				pTaskFile->Sector_Count_Exp = pReq->Cdb[7];

				pTaskFile->LBA_Low = pReq->Cdb[5];
				pTaskFile->LBA_Mid = pReq->Cdb[4];
				pTaskFile->LBA_High = pReq->Cdb[3];
				pTaskFile->LBA_Low_Exp = pReq->Cdb[2];

				pTaskFile->Device = MV_BIT(6);

				pTaskFile->Command = ATA_CMD_VERIFY_EXT;
			}
			else
			{
				pTaskFile->Sector_Count = pReq->Cdb[8];
				
				pTaskFile->LBA_Low = pReq->Cdb[5];
				pTaskFile->LBA_Mid = pReq->Cdb[4];
				pTaskFile->LBA_High = pReq->Cdb[3];

				pTaskFile->Device = MV_BIT(6) | (pReq->Cdb[2]&0xF);
				
				MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );

				pTaskFile->Command = ATA_CMD_VERIFY;				
			}

			break;

		case SCSI_CMD_MARVELL_SPECIFIC:
			{
				/* This request should be for core module */
				if ( pReq->Cdb[1]!=CDB_CORE_MODULE )
					return MV_FALSE;
				
				switch ( pReq->Cdb[2] )
				{
					case CDB_CORE_IDENTIFY:
						pTaskFile->Command = ATA_CMD_IDENTIFY_ATA;
						break;
					case CDB_CORE_SET_UDMA_MODE:
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
						pTaskFile->Sector_Count = 0x40 | pReq->Cdb[3];
						MV_DASSERT( pReq->Cdb[4]==MV_FALSE );	/* Use UDMA mode */
						break;

					case CDB_CORE_SET_PIO_MODE:
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_SET_TRANSFER_MODE;
						pTaskFile->Sector_Count = 0x08 | pReq->Cdb[3];
						break;

					case CDB_CORE_ENABLE_WRITE_CACHE:
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_ENABLE_WRITE_CACHE;
						 pDevice->Setting |= DEVICE_SETTING_WRITECACHE_ENABLED;
						break;
			
					case CDB_CORE_DISABLE_WRITE_CACHE:
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_DISABLE_WRITE_CACHE;
						 pDevice->Setting &= ~DEVICE_SETTING_WRITECACHE_ENABLED;
						break;
						
					case CDB_CORE_SHUTDOWN:
						if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
							pTaskFile->Command = ATA_CMD_FLUSH_EXT;
						else
							pTaskFile->Command = ATA_CMD_FLUSH;
						break;

                      	 #ifdef SUPPORT_ATA_POWER_MANAGEMENT
					case CDB_CORE_ATA_IDLE:
						pTaskFile->Command = 0xe3;
						pTaskFile->Sector_Count = pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?4:6];
							break;
					case CDB_CORE_ATA_STANDBY:
						pTaskFile->Command = 0xe2;
							break;
					case CDB_CORE_ATA_IDLE_IMMEDIATE:
						pTaskFile->Command = 0xe1;
							break;
					case CDB_CORE_ATA_STANDBY_IMMEDIATE:
						pTaskFile->Command = 0xe0;
							break;
					case CDB_CORE_ATA_CHECK_POWER_MODE:
						pTaskFile->Command = 0xe5;
							break;
                         	        case CDB_CORE_ATA_SLEEP:
                                               	pTaskFile->Command = 0xe6;
                                               	break;
                         #endif
					case CDB_CORE_ATA_IDENTIFY:
						pTaskFile->Command = 0xec;
						break;

					case CDB_CORE_ENABLE_READ_AHEAD:	
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_ENABLE_READ_LOOK_AHEAD;
						break;

					case CDB_CORE_DISABLE_READ_AHEAD:
						pTaskFile->Command = ATA_CMD_SET_FEATURES;
						pTaskFile->Features = ATA_CMD_DISABLE_READ_LOOK_AHEAD;
						break;
					
					case CDB_CORE_READ_LOG_EXT:
						pTaskFile->Command = ATA_CMD_READ_LOG_EXT;
						pTaskFile->Sector_Count = 1;	/* Read one sector */
						pTaskFile->LBA_Low = 0x10;		/* Page 10h */
						break;

					case CDB_CORE_OS_SMART_CMD:
						pTaskFile->Command = pReq->Cdb[3];
						pTaskFile->Features = pReq->Cdb[4];
						pTaskFile->LBA_Low = pReq->Cdb[5];
						pTaskFile->LBA_Mid  = pReq->Cdb[6];
						pTaskFile->LBA_High = pReq->Cdb[7];
						pTaskFile->LBA_Low_Exp = pReq->Cdb[9];
						pTaskFile->Sector_Count = pReq->Cdb[8];
						break;
				#ifdef SUPPORT_ATA_SMART
					case CDB_CORE_ATA_IDENTIFY_PACKET_DEVICE:
						pTaskFile->Command = ATA_IDENTIFY_PACKET_DEVICE;
						pTaskFile->Sector_Count = 0x1;
						break;
					case CDB_CORE_ENABLE_SMART:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_CMD_ENABLE_SMART;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low = 0x1;
						break;
					case CDB_CORE_DISABLE_SMART:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_CMD_DISABLE_SMART;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low = 0x1;
						break;
					case CDB_CORE_SMART_RETURN_STATUS:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_CMD_SMART_RETURN_STATUS;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						break;	
					case CDB_CORE_ATA_SMART_READ_VALUES:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_READ_VALUES;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low = 0x1;
						break;
					case CDB_CORE_ATA_SMART_READ_THRESHOLDS:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_READ_THRESHOLDS;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low = 0x1;
						break;
					case CDB_CORE_ATA_SMART_READ_LOG_SECTOR:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_READ_LOG_SECTOR;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->Sector_Count = 0x1;
						pTaskFile->LBA_Low = pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?5:8];
						break;
					case CDB_CORE_ATA_SMART_WRITE_LOG_SECTOR :
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_WRITE_LOG_SECTOR;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->Sector_Count = 0x1;
						pTaskFile->LBA_Low = pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?5:8];
						break;
					case  CDB_CORE_ATA_SMART_AUTO_OFFLINE:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_AUTO_OFFLINE;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low= pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?5:8];
						pTaskFile->Sector_Count = pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?4:6];
						break;
					case CDB_CORE_ATA_SMART_AUTOSAVE:    
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_AUTOSAVE;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->Sector_Count =  pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?4 : 6];
						break;
					case CDB_CORE_ATA_SMART_IMMEDIATE_OFFLINE:
						pTaskFile->Command = ATA_CMD_SMART;
						pTaskFile->Features = ATA_SMART_IMMEDIATE_OFFLINE;
						pTaskFile->LBA_Mid = 0x4F;
						pTaskFile->LBA_High = 0xC2;
						pTaskFile->LBA_Low= pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?5:8];
						pTaskFile->Sector_Count =  pReq->Cdb[(pReq->Cmd_Flag & CMD_FLAG_ATA_12) ?4 : 6];
						break;
				#endif /*#ifdef SUPPORT_ATA_SMART*/
					case CDB_CORE_ATA_DOWNLOAD_MICROCODE:
						if(pReq->Cmd_Flag & CMD_FLAG_ATA_12)
							scsi_ata_passthru_12_fill_taskfile(pReq,pTaskFile);
						else
							scsi_ata_passthru_16_fill_taskfile(pReq,pTaskFile);
						break;
					default:
						return MV_FALSE;
				}
				break;
			}

		case SCSI_CMD_SYNCHRONIZE_CACHE_10:
			if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )
				pTaskFile->Command = ATA_CMD_FLUSH_EXT;
			else
				pTaskFile->Command = ATA_CMD_FLUSH;
			pTaskFile->Device = MV_BIT(6);
			break;
		case SCSI_CMD_START_STOP_UNIT:
			if (pReq->Cdb[4] & MV_BIT(0))
			{
				pTaskFile->Command = ATA_CMD_SEEK;
				pTaskFile->Device = MV_BIT(6);
			}
			else
			{
				pTaskFile->Command = ATA_CMD_STANDBY_IMMEDIATE;
			}
			break;
		case SCSI_CMD_SND_DIAG:
			Core_Fill_SendDiagTaskfile( pDevice,pReq, pTaskFile);
			break;
		case SCSI_CMD_REQUEST_SENSE:
		case SCSI_CMD_MODE_SELECT_10:
		case SCSI_CMD_MODE_SENSE_10:
			MV_DPRINT(("Error: Unknown request: 0x%x.\n", pReq->Cdb[0]));

		default:
			return MV_FALSE;
	}

	/* 
	 * Attention: Never return before this line if your return is MV_TRUE.
	 * We need set the slave DEV bit here. 
	 */
	if ( pDevice->Is_Slave )		
		pTaskFile->Device |= MV_BIT(4);

	return MV_TRUE;
}