📄 satadrv.c
字号:
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 + -