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

📄 satadrv.c

📁 vxworks下SATA控制器SIL3124A的驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
									pDrive->singleDmaMode = 0;
								
								pDrive->multiDmaMode  = -1;
								if (pParam->multiDma & 0x04)
									pDrive->multiDmaMode = 2;
								else if (pParam->multiDma & 0x02)
									pDrive->multiDmaMode = 1;
								else if (pParam->multiDma & 0x01)
									pDrive->multiDmaMode = 0;
							}
							
					pDrive->ultraDmaMode = -1;
					if( pParam->valid & 0x04 )
							{
								if (pParam->ultraDmaMode & 0x04 )
									pDrive->ultraDmaMode = 2;
								else if( pParam->ultraDmaMode & 0x02 )
									pDrive->ultraDmaMode = 1;
								else if( pParam->ultraDmaMode & 0x01 )
									pDrive->ultraDmaMode = 0;
							}
				}


    /* find out transfer mode to use */

    pDrive->rwBits = configType & ATA_BITS_MASK;
    pDrive->rwPio  = configType & ATA_PIO_MASK;
    pDrive->rwDma  = configType & ATA_DMA_MASK;
    pDrive->rwMode = ATA_PIO_DEF_W;

    switch (configType & ATA_MODE_MASK)
        {
        case ATA_PIO_0:
        case ATA_PIO_1:
        case ATA_PIO_2:
        case ATA_PIO_3:
        case ATA_PIO_4:
        case ATA_PIO_DEF_0:
        case ATA_PIO_DEF_1:
            pDrive->rwMode = configType & ATA_MODE_MASK;
            ourRwMode = ATA_PIO;
            break;

        case ATA_PIO_AUTO:
            pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
            ourRwMode = ATA_PIO;
            break;

        case ATA_DMA_0:
        case ATA_DMA_1:
        case ATA_DMA_2:

            if (pDrive->okDma)
							{
				
								if (pDrive->rwDma == ATA_DMA_SINGLE)
									{
										pDrive->rwMode = ATA_DMA_SINGLE_0 + (configType & ATA_MODE_MASK) - ATA_DMA_0;
										ourRwMode = ATA_MDMA;
									}
								if (pDrive->rwDma == ATA_DMA_MULTI)
									{
										pDrive->rwMode = ATA_DMA_MULTI_0 + (configType & ATA_MODE_MASK) - ATA_DMA_0;
										ourRwMode = ATA_MDMA;
									}

								if (pDrive->rwDma == ATA_DMA_ULTRA)
									{
										pDrive->rwMode = ATA_DMA_ULTRA_0 + (configType & ATA_MODE_MASK) - ATA_DMA_0;
										ourRwMode = ATA_UDMA;
									}
							}
						break;

        case ATA_DMA_AUTO:

            if (pDrive->okDma)
                {

                		{
                    	pDrive->rwMode = ATA_DMA_SINGLE_0 + pDrive->singleDmaMode;
                    	ourRwMode = ATA_MDMA;
										}
                	if (pDrive->multiDmaMode >= 0)
                		{
                    	pDrive->rwMode = ATA_DMA_MULTI_0 + pDrive->multiDmaMode;
                    	ourRwMode = ATA_MDMA;
                		}
                	if (pDrive->ultraDmaMode >= 0)
                		{
											pDrive->rwMode = ATA_DMA_ULTRA_0 + pDrive->ultraDmaMode;
											ourRwMode = ATA_UDMA;
										}
                }
             else
             		{
             			 pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
             			 ourRwMode = ATA_PIO;
             		}
            break;

        default:
            break;

        }
   
    /* Set multiple mode (multisector read/write) */

    if ((pDrive->rwPio == ATA_PIO_MULTI) && (pDrive->type == SATA_TYPE_ATA))
        {

        if (pDrive->okMulti)
            (void) sataCmd (ctrl, drive, ATA_CMD_SET_MULTI,
                           pDrive->multiSecs, 0);
        else
            pDrive->rwPio = ATA_PIO_SINGLE;
        }
 		/* Set multiple mode (multisector read/write) for all mode just device supported*/
    if (pDrive->okMulti)
       (void) sataCmd (ctrl, drive, ATA_CMD_SET_MULTI, pDrive->multiSecs, 0);

    /* enable look ahead function if device supported just for best performance */
    if(pParam->commandSetSup1 & 0x0040)
        (void) sataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_ENABLE_LOOK, 0);

    /* enable write cache function if device supported just for best performance */
    if(pParam->commandSetSup1 & 0x0020)
        (void) sataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_ENABLE_WCACHE, 0);
    
     /* Set the transfer mode */
    (void) sataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE, pDrive->rwMode);

		pDrive->state = SATA_DEV_OK;

driveInitExit:

    semGive (&pCtrl->muteSem);

    if (pDrive->state != SATA_DEV_OK)
        {
        MOT_SATA_LOG (MOT_SATA_DBG_INIT, "sataDriveInit error! \n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    return (OK);
    } /* ataDriveInit */

/*******************************************************************************
*
* sataCmd - issue non data command
*
* Issue a non data command.  Non data commands have the same protocol.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/

LOCAL STATUS sataCmd
    (
    int ctrl,
    int drive,
    int cmd,
    int arg0,
    int arg1
    )
    {
    SATA_CTRL *pCtrl	= &sataCtrl[ctrl];
    SATA_TYPE *pType	= &sataTypes[ctrl][drive];
    BOOL     retry	= TRUE;
    int      retryCount	= 0;
    char 		 *ident_param = NULL;
    int      semStatus;
    
    MOT_SATA_LOG (MOT_SATA_DBG_SATACMD, "sataCmd%d/%d: cmd=0x%x\n", ctrl, drive, cmd, arg0, arg1, 0);
    
    ident_param = memalign (8, 4096);
  	if ( ident_param == NULL )
  	{
  		MOT_SATA_LOG(MOT_SATA_DBG_SATACMD,"could not obtain memory!\n",1,2,3,4,5,6);	
  		return (ERROR);
  	}
  	while (retry)
		{
		memset(ident_param, 0, 4096);
  	MOT_SATA_LOG(MOT_SATA_DBG_SATACMD,"ident_param = 0x%x!\n",(UINT32)ident_param,2,3,4,5,6);	
 		switch (cmd)
	    {
	    case ATA_CMD_DIAGNOSE:
      
      /* fill in the PRB slot 0 */
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00908027);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), 0xa0000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		
			break;

	    case ATA_CMD_INITP:
			/* fill in the PRB slot 0 */
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00918027);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), (pType->cylinders << 8) |((ATA_SDH_IBM |((pType->heads - 1) & 0x0f)) << 24));
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), pType->sectors);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		break;

	    case ATA_CMD_RECALIB:
			sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00108027);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), 0xa0000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		break;

	    case ATA_CMD_SEEK:
			sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00708027);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), (arg0 << 8) |((ATA_SDH_IBM  | (arg1 & 0x0f)) << 24));
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		break;

	    case ATA_CMD_SET_FEATURE:
      sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00EF8027 | arg0 << 24);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), 0xa0000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), arg1);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		break;

	    case ATA_CMD_SET_MULTI:
      sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 4), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 8), 0x00C68027);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 12), 0xa0000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 16), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 20), arg0);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 24), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 28), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 32), (UINT32)ident_param);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 36), 0x00000000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 40), 0x00001000);
  		sysPciOutLong((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + 44), 0x80000000);
  		break;

	    }
					
			/* write excutin FIFO */
			sysPciOutLong ((UINT32*)(pCtrl->portAddr + drive * PORT_REGS_SIZE + PORT_EXEC_FIFO), 0x0);        
			
      semStatus = semTake (&pCtrl->syncSem, 
			     sysClkRateGet() * pCtrl->semTimeout);
			
      if((semStatus == ERROR) || (pCtrl->intStatus))
			{
			MOT_SATA_LOG(MOT_SATA_DBG_SATACMD," sataCmd: command  excuted failed!\n",1,2,3,4,5,6);	
			if (++retryCount > ataRetry)
				{
					free(ident_param);
	        return (ERROR);
	      }
		}
		else
	    retry = FALSE;
	}

    MOT_SATA_LOG (MOT_SATA_DBG_SATACMD, "sataCmd end - ctrl %d, drive %d: Ok\n", ctrl, drive, 0, 0, 0, 0);
		free(ident_param);
    return (OK);
    }

/*******************************************************************************
*
* sataDevCreate - create a device for a SATA/IDE disk
*
* This routine creates a device for a specified SATA/IDE or ATAPI CDROM disk.
*
* <ctrl> is a controller number for the SATA controller; the primary controller
* is 0.  The maximum is specified via SATA_MAX_CTRLS.
*
* <drive> is the drive number for the ATA hard drive; the master drive
* is 0.  The maximum is specified via SATA_MAX_DRIVES.
*
* The <nBlocks> parameter specifies the size of the device in blocks.
* If <nBlocks> is zero, the whole disk is used.
*
* The <blkOffset> parameter specifies an offset, in blocks, from the start
* of the device to be used when writing or reading the hard disk.  This
* offset is added to the block numbers passed by the file system during
* disk accesses.  (VxWorks file systems always use block numbers beginning
* at zero for the start of a device.)
*
*
* RETURNS:
* A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
* be allocated for the device structure.
*
* SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
* rawFsDevInit()
*/

BLK_DEV *sataDevCreate
    (
    int ctrl,     /* SATA controller number, 0 is the primary controller */
    int drive,    /* SATA drive number, 0 is the master drive */
    int nBlocks,  /* number of blocks on device, 0 = use entire disc */
    int blkOffset /* offset BLK_DEV nBlocks from the start of the drive */
    )
{
    SATA_CTRL  *pCtrl	= &sataCtrl[ctrl];
    SATA_TYPE  *pType	= &sataTypes[ctrl][drive];
    SATA_DRIVE *pDrive	= &pCtrl->drive[drive];
    SATA_DEV   *pDev;
    BLK_DEV   *pBlkdev;
    int	      maxBlks;
    
    MOT_SATA_LOG(MOT_SATA_DBG_CREATE,"Enter into sataDevCreate!\n",1,2,3,4,5,6);	
		
    if ((ctrl >= SATA_MAX_CTRLS) || (drive >= SATA_MAX_DRIVES) ||
        !sataDrvInstalled || !pCtrl->installed)
			return (NULL);

    if ((pDev = (SATA_DEV *)malloc(sizeof (SATA_DEV))) == NULL)
			return (NULL);

    pBlkdev = &pDev->blkDev;

    if ((pDrive->state == SATA_DEV_OK) || (pDrive->state == SATA_DEV_MED_CH))
    	{
        pDrive->state = SATA_DEV_MED_CH;

        if (pDrive->type == SATA_TYPE_ATA)
        	{

	    /* 
	     * if LBA is supported and ataLbaTotalSecs is not zero
	     * and ataLbaTotalSecs is greater than the product of
	     * CHS, then we should use the LBA value.
	     */

            if ((pDrive->okLba == TRUE)                     && 
								(ataLbaTotalSecs[ctrl][drive] != 0)         &&
								(ataForceCHSonLBA != TRUE)		    &&
								(ataLbaTotalSecs[ctrl][drive] > 
		 						(pType->cylinders * pType->heads * pType->sectors)))   
	        		{
								maxBlks = (ataLbaTotalSecs[ctrl][drive]) - blkOffset;
							}
	    			else /* just use CHS */
	        		{
								maxBlks = ((pType->cylinders * pType->heads * pType->sectors) 
			   									- blkOffset);
							}

	    			if (nBlocks == 0)
	        		nBlocks = maxBlks;
    
	    			if (nBlocks > maxBlks)
	        		nBlocks = maxBlks;

	   				pBlkdev->bd_nBlocks		= nBlocks;
	    			pBlkdev->bd_bytesPerBlk	= pType->bytes;
	    			pBlkdev->bd_blksPerTrack	= pType->sectors;
	    			pBlkdev->bd_nHeads		= pType->heads;
	    			pBlkdev->bd_removable	= FALSE;
	    			pBlkdev->bd_retry		= 0;
	    			pBlkdev->bd_mode		= O_RDWR;
	    			pBlkdev->bd_readyChanged	= TRUE;
	    			pBlkdev->bd_blkRd		= sataBlkRd;
	    			pBlkdev->bd_blkWrt		= sataBlkWrt;
	    			pBlkdev->bd_ioctl		= sataIoctl;
	    			pBlkdev->bd_reset		= sataReset;
	    			pBlkdev->bd_statusChk	= sataStatus;
	    			pDev->ctrl			= ctrl;
	    			pDev->drive			= drive;
	    			pDev->blkOffset		= blkOffset;
	    		}
        
        sataDriveInit (ctrl, drive);

        pDrive->state = SATA_DEV_OK;
			}

⌨️ 快捷键说明

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