示例#1
0
void sgd_test()
{
	sgd_tbl_t SgTbl1 = {0,};
	sgd_tbl_t SgTbl2 = {0,};
	sgd_tbl_t SgTbl3 = {0,};
	sgd_t Entries1[32];
	sgd_t Entries2[32];
	sgd_t Entries3[32];

	SgTbl1.Max_Entry_Count = sizeof(Entries1)/sizeof(Entries1[0]);
	SgTbl1.Entry_Ptr = Entries1;

	SgTbl2.Max_Entry_Count = sizeof(Entries2)/sizeof(Entries2[0]);
	SgTbl2.Entry_Ptr = Entries2;

	SgTbl3.Max_Entry_Count = sizeof(Entries3)/sizeof(Entries3[0]);
	SgTbl3.Entry_Ptr = Entries3;

	int i;

	for( i = 0; i < 32; i++ )
	{
		sgdt_append( &SgTbl2, 0x80000000+i*0x1000, 0x90000000, 0x1000 );
	}

	sgdt_dump( &SgTbl2, " " );

	sgdt_append_reftbl( &SgTbl1, &SgTbl2, 0x3800, 0x1000*10 );
	sgdt_append_virtual( &SgTbl1, (MV_PVOID)0x40000, (MV_PVOID)0x60000, 0x1000*10 );
	sgdt_append_vp( &SgTbl1, (MV_PVOID)0x80000, 0x1000*10, 0x4000, 0 );

	sgdt_dump( &SgTbl1, " " );

	MV_PRINT( "Walking through the table:\n" );

	MV_U32 index = 0;
	sgd_table_walk( &SgTbl1, SgVisitor, &index );

	sgd_iter_t iter;
	sgd_t sg[2];

	sgd_iter_init( &iter, SgTbl1.Entry_Ptr, 0, SgTbl1.Byte_Count );

	MV_PRINT( "Walking through the table in another way:\n" );
	i = 0;
	while( sgd_iter_get_next( &iter, sg ) )
	{
		sgd_dump( sg, NULL );
	}

	sgdt_dump( &SgTbl1, " " );
	sgd_t* sgd = SgTbl1.Entry_Ptr;
	MV_U32 off = 0x1000;
	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );
	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x9000 );
	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x9000 );
	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );
	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );
	sgdt_dump( &SgTbl3, " " );
}
示例#2
0
/*****************************************************************************
*
* mv_phyCheckStatusChange -- checks for significant changes in PHY state.
*
* A "significant change" is:
*     dropped link (e.g. ethernet cable unplugged) OR
*     autonegotiation completed + link (e.g. ethernet cable plugged in)
*/
void
mv_phyCheckStatusChange(int ethUnit)
{
    int           phyUnit;
    UINT16        phyHwStatus;
    mvPhyInfo_t   *lastStatus;
    int           linkCount   = 0;
    int           lostLinks   = 0;
    int           gainedLinks = 0;
    UINT32        phyBase;
    UINT32        phyAddr;

    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        phyBase = MV_PHYBASE(phyUnit);
        phyAddr = MV_PHYADDR(phyUnit);

        lastStatus = &mvPhyInfo[phyUnit];
        phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);

        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
            /* See if we've lost link */
            if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {
                linkCount++;
            } else {
                lostLinks++;
                mv_flushATUDB(phyUnit);
                MV_PRINT(MV_DEBUG_PHYCHANGE,("\neth%d port%d down\n",
                                               ethUnit, phyUnit));
                lastStatus->isPhyAlive = FALSE;
            }
        } else { /* last known link status was DEAD */
            /* Check for AutoNegotiation complete */
            if (MV_AUTONEG_DONE(phyHwStatus)) {
                gainedLinks++;
		linkCount++;
                MV_PRINT(MV_DEBUG_PHYCHANGE,("\neth%d port%d up\n",
                                               ethUnit, phyUnit));
                lastStatus->isPhyAlive = TRUE;
            }
        }
    }

    if (linkCount == 0) {
        if (lostLinks) {
            /* We just lost the last link for this MAC */
            phyLinkLost(ethUnit);
        }
    } else {
        if (gainedLinks == linkCount) {
            /* We just gained our first link(s) for this MAC */
            phyLinkGained(ethUnit);
        }
    }
}
示例#3
0
void sgdt_dump(sgd_tbl_t *SgTbl, char* prefix)
{
	sgd_t* sg = SgTbl->Entry_Ptr;

	MV_PRINT( "%s %p %u of %u 0x%x bytes\n"
		, prefix ? prefix : " "
		, SgTbl
		, SgTbl->Valid_Entry_Count
		, SgTbl->Max_Entry_Count
		, SgTbl->Byte_Count
		);

	if( !SgTbl->Valid_Entry_Count )
		return;

#if 0
	sgdl_dump(sg, NULL);
#else
	while(1)
	{

		sgd_dump(sg,NULL);
		if( sgd_eot(sg) )
			break;
		sgd_inc(sg);
	}
#endif
}
示例#4
0
/******************************************************************************
*
* mv_phySetup - reset and setup the PHY switch.
*
* Resets each PHY port.
*
* RETURNS:
*    TRUE  --> at least 1 PHY with LINK
*    FALSE --> no LINKs on this ethernet unit
*/
BOOL
mv_phySetup(int ethUnit, UINT32 phyBase)
{
    int     phyUnit;
    int     liveLinks = 0;
    BOOL    foundPhy = FALSE;
    UINT32  phyAddr;
    UINT16  atuControl;

    /*
     * See if there's any configuration data for this enet,
     * and set up phyBase in table.
     */
    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (MV_ETHUNIT(phyUnit) != ethUnit) {
            continue;
        }

        MV_PHYBASE(phyUnit) = phyBase;
        foundPhy = TRUE;
    }

    if (!foundPhy) {
        return FALSE; /* No PHY's configured for this ethUnit */
    }

    /* Verify that the switch is what we think it is, and that it's ready */
    mv_verifyReady(ethUnit);

    /* Initialize global switch settings */
    atuControl  = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT;
    atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT;
    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl);

    /* Reset PHYs and start autonegoation on each. */
    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (MV_ETHUNIT(phyUnit) != ethUnit) {
            continue;
        }

        phyBase = MV_PHYBASE(phyUnit);
        phyAddr = MV_PHYADDR(phyUnit);

        phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL,
                    MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE);
    }

#if 0 /* Don't wait -- we'll detect shortly after the link comes up */
{
    int timeout;
    UINT16  phyHwStatus;

    /*
     * Wait 5 seconds for ALL associated PHYs to finish autonegotiation.
     */
    timeout=50;
    for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) {
        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        for (;;) {
            phyBase = MV_PHYBASE(phyUnit);
            phyAddr = MV_PHYADDR(phyUnit);

            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);

            if (MV_AUTONEG_DONE(phyHwStatus)) {
                break;
            }

            if (--timeout == 0) {
                break;
            }

            sysMsDelay(100);
        }
    }
}
#endif

    /*
     * All PHYs have had adequate time to autonegotiate.
     * Now initialize software status.
     *
     * It's possible that some ports may take a bit longer
     * to autonegotiate; but we can't wait forever.  They'll
     * get noticed by mv_phyCheckStatusChange during regular
     * polling activities.
     */
    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        if (mv_phyIsLinkAlive(phyUnit)) {
            liveLinks++;
            MV_IS_PHY_ALIVE(phyUnit) = TRUE;
        } else {
            MV_IS_PHY_ALIVE(phyUnit) = FALSE;
        }

        MV_PRINT(MV_DEBUG_PHYSETUP,
            ("eth%d: Phy Status=%4.4x\n",
            ethUnit, 
            phyRegRead(MV_PHYBASE(phyUnit),
                       MV_PHYADDR(phyUnit),
                       MV_PHY_SPECIFIC_STATUS)));
    }

    mv_VLANInit(ethUnit);

    mv_enableConfiguredPorts(ethUnit);

    return (liveLinks > 0);
}
示例#5
0
/******************************************************************************
*
* mv_verifyReady - validates that we're dealing with the device
* we think we're dealing with, and that it's ready.
*/
LOCAL void
mv_verifyReady(int ethUnit)
{
    int     phyUnit;
    UINT16  globalStatus;
    UINT32  phyBase = 0;
    UINT32  phyAddr;
    UINT32  switchPortAddr;
    UINT16  phyID1;
    UINT16  phyID2;
    UINT16  switchID;

    /*
     * The first read to the Phy port registers always fails and
     * returns 0.   So get things started with a bogus read.
     */
    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        phyBase = MV_PHYBASE(phyUnit);
        phyAddr = MV_PHYADDR(phyUnit);
    
        (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */
        break;
    }

    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }

        /*******************/
        /* Verify phy port */
        /*******************/
        phyBase = MV_PHYBASE(phyUnit);
        phyAddr = MV_PHYADDR(phyUnit);
    
        phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1);
        if (phyID1 != MV_PHY_ID1_EXPECTATION) {
            MV_PRINT(MV_DEBUG_PHYSETUP,
                      ("Invalid PHY ID1 for eth%d port%d.  Expected 0x%04x, read 0x%04x\n",
                       ethUnit,
                       phyUnit,
                       MV_PHY_ID1_EXPECTATION,
                       phyID1));
            return;
        }
    
        phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2);
        if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) {
            MV_PRINT(MV_DEBUG_PHYSETUP,
                      ("Invalid PHY ID2 for eth%d port %d.  Expected 0x%04x, read 0x%04x\n",
                       ethUnit,
                       phyUnit,
                       MV_OUI_LSB_EXPECTATION,
                       phyID2));
            return;
        }
    
        MV_PRINT(MV_DEBUG_PHYSETUP,
                  ("Found PHY eth%d port%d: model 0x%x revision 0x%x\n",
                   ethUnit,
                   phyUnit,
                   (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT,
                   (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT));
    
    
        /**********************/
        /* Verify switch port */
        /**********************/
        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
    
        switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID);
        if ((switchID & MV_SWITCH_ID_DEV_MASK) !=
            MV_SWITCH_ID_DEV_EXPECTATION) {
    
            MV_PRINT(MV_DEBUG_PHYSETUP,
                      ("Invalid switch ID for eth%d port %d.  Expected 0x%04x, read 0x%04x\n",
                       ethUnit,
                       phyUnit,
                       MV_SWITCH_ID_DEV_EXPECTATION,
                       switchID));
            return;
        }
    
        MV_PRINT(MV_DEBUG_PHYSETUP,
                  ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n",
                    ethUnit,
                    phyUnit,
                    (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT,
                    (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT))
    }
    
    /*******************************/
    /* Verify that switch is ready */
    /*******************************/
    if (phyBase) {
        globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
                                  MV_SWITCH_GLOBAL_STATUS);

        if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) {
            MV_PRINT(MV_DEBUG_PHYSETUP,
                      ("PHY switch for eth%d NOT ready!\n",
                       ethUnit));
        }
    } else {
        MV_PRINT(MV_DEBUG_PHYSETUP,
                  ("No ports configured for eth%d\n", ethUnit));
    }
}
示例#6
0
MV_BOOLEAN mvui_init_param( MV_PVOID This, pHBA_Info_Page pHBA_Info_Param)
{
//	MV_U32 					nsize = FLASH_PARAM_SIZE;
	MV_U32 					param_flash_addr=PARAM_OFFSET,i = 0;
//	MV_U16 					my_ds=0;
	PCore_Driver_Extension	pCore;
	AdapterInfo				AI;

	if (!This)
		return MV_FALSE;

	pCore = (PCore_Driver_Extension)This;
	AI.bar[2] = pCore->Base_Address[2];

	if (-1 == OdinSPI_Init(&AI))
		return MV_FALSE;

	/* step 1 read param from flash offset = 0x3FFF00 */
	OdinSPI_ReadBuf( &AI, param_flash_addr, (MV_PU8)pHBA_Info_Param, FLASH_PARAM_SIZE);

	/* step 2 check the signature first */
	if(pHBA_Info_Param->Signature[0] == 'M'&& \
	    pHBA_Info_Param->Signature[1] == 'R'&& \
	    pHBA_Info_Param->Signature[2] == 'V'&& \
	    pHBA_Info_Param->Signature[3] == 'L' && \
	    (!mvVerifyChecksum((MV_PU8)pHBA_Info_Param,FLASH_PARAM_SIZE)))
	{
		if(pHBA_Info_Param->HBA_Flag == 0xFFFFFFFFL)
		{
			pHBA_Info_Param->HBA_Flag = 0;
			pHBA_Info_Param->HBA_Flag |= HBA_FLAG_INT13_ENABLE;
			pHBA_Info_Param->HBA_Flag &= ~HBA_FLAG_SILENT_MODE_ENABLE;
		}

		for(i=0;i<8;i++)
		{
			if(pHBA_Info_Param->PHY_Rate[i]>0x1)
				/* phy host link rate */
				pHBA_Info_Param->PHY_Rate[i] = 0x1;

			// validate phy tuning
			//pHBA_Info_Param->PHY_Tuning[i].Reserved[0] = 0;
			//pHBA_Info_Param->PHY_Tuning[i].Reserved[1] = 0;
		}
	}
	else
	{
		MV_FillMemory((MV_PVOID)pHBA_Info_Param, FLASH_PARAM_SIZE, 0xFF);
		pHBA_Info_Param->Signature[0] = 'M';	
		pHBA_Info_Param->Signature[1] = 'R';
	   	pHBA_Info_Param->Signature[2] = 'V';
	    pHBA_Info_Param->Signature[3] = 'L';

		// Set BIOS Version
		pHBA_Info_Param->Minor = NVRAM_DATA_MAJOR_VERSION;
		pHBA_Info_Param->Major = NVRAM_DATA_MINOR_VERSION;
		
		// Set SAS address
		for(i=0;i<MAX_PHYSICAL_PORT_NUMBER;i++)
		{
			pHBA_Info_Param->SAS_Address[i].b[0]=  0x50;
			pHBA_Info_Param->SAS_Address[i].b[1]=  0x05;
			pHBA_Info_Param->SAS_Address[i].b[2]=  0x04;
			pHBA_Info_Param->SAS_Address[i].b[3]=  0x30;
			pHBA_Info_Param->SAS_Address[i].b[4]=  0x11;
			pHBA_Info_Param->SAS_Address[i].b[5]=  0xab;
			pHBA_Info_Param->SAS_Address[i].b[6]=  0x00;
			pHBA_Info_Param->SAS_Address[i].b[7]=  0x00; 
			/*+(MV_U8)i; - All ports' WWN has to be same */
		}
		
		/* init phy link rate */
		for(i=0;i<8;i++)
		{
			/* phy host link rate */
			pHBA_Info_Param->PHY_Rate[i] = 0x1;//Default is 3.0G;
		}

		MV_PRINT("pHBA_Info_Param->HBA_Flag = 0x%x \n",pHBA_Info_Param->HBA_Flag);

		/* init setting flags */
		pHBA_Info_Param->HBA_Flag = 0;
		pHBA_Info_Param->HBA_Flag |= HBA_FLAG_INT13_ENABLE;
		pHBA_Info_Param->HBA_Flag &= ~HBA_FLAG_SILENT_MODE_ENABLE;
		/* write to flash and save it now */
		if(OdinSPI_SectErase( &AI, param_flash_addr) != -1)
			MV_PRINT("FLASH ERASE SUCCESS\n");
		else
			MV_PRINT("FLASH ERASE FAILED\n");

		pHBA_Info_Param->Check_Sum = 0;
		pHBA_Info_Param->Check_Sum=mvCaculateChecksum((MV_PU8)pHBA_Info_Param,sizeof(HBA_Info_Page));
		/* init the parameter in ram */
		OdinSPI_WriteBuf( &AI, param_flash_addr, (MV_PU8)pHBA_Info_Param, FLASH_PARAM_SIZE);
	}
	return MV_TRUE;
}
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;
}
示例#9
0
void sgd_dump(sgd_t* sg, char* prefix)
{
	MV_U32	sz;

	sgd_getsz(sg,sz);

	if( prefix )
	{
#ifndef _OS_LINUX
		MV_PRINT(prefix);
#endif
	}

	if( sg->flags & SGD_VIRTUAL )
	{
		MV_PVOID vaddr, xctx;

		sgd_get_vaddr(sg,vaddr);
		sgd_get_xctx(sg,xctx);

		MV_PRINT( "\tV %p T %p %08x F %08x\n"
			, vaddr
			, xctx
			, sz
			, sg->flags );
	}
	else if( sg->flags & (SGD_REFTBL|SGD_REFSGD) )
	{
		MV_PVOID ref;
		MV_U32	refOff;

		sgd_get_ref(sg,ref);
		sgd_get_refoff(sg,refOff);

		MV_PRINT( "\tR %p O %08x %08x F %08x\n"
			, ref
			, refOff
			, sz
			, sg->flags );
	}
	else if( sg->flags & SGD_NEXT_TBL )
	{
		MV_PVOID nexttbl;

		sgd_get_nexttbl(sg, nexttbl);

		MV_PRINT( "\tN %p F %08x\n"
			, nexttbl, sg->flags );

	}
	else if( sg->flags & SGD_VP )
	{
		sgd_vp_t* vp = (sgd_vp_t*) sg;
		MV_PRINT( "\tX %08x_%08x %p F %08x\n"
			, vp->baseAddr.parts.high
			, vp->baseAddr.parts.low
			, vp->u.vaddr
			, sg->flags );
	}
	else if( sg->flags & SGD_VWOXCTX )
	{
		sgd_v_t* vp = (sgd_v_t*) sg;

		MV_PRINT( "\tV %p T %p %08x F %08x\n"
			, vp->u.vaddr
			, (MV_PVOID)0
			, sz
			, sg->flags );
	}
	else if( sg->flags & SGD_PCTX )
	{
		sgd_pctx_t* p = (sgd_pctx_t*) sg;
		MV_PRINT( "\tP %08x_%08x %08x F %08x X %p\n"
			, p->baseAddr.parts.high, p->baseAddr.parts.low, p->size, p->flags
			, p->u.xctx );
	}
	else
	{
		MV_PRINT( "\tP %08x_%08x %08x F %08x\n"
		, sg->baseAddr.parts.high, sg->baseAddr.parts.low, sz, sg->flags );
	}
}