📄 nwatadrv.c
字号:
(void) ataCmd (ctrl, drive, ATA_CMD_RECALIB, 0, 0);
/* find out supported capabilities of the drive */
pDrive->multiSecs = pParam->multiSecs & 0x00ff;
pDrive->okMulti = (pDrive->multiSecs) ? TRUE : FALSE;
pDrive->okIordy = (pParam->capabilities & 0x0800) ? TRUE : FALSE;
pDrive->okLba = (pParam->capabilities & 0x0200) ? TRUE : FALSE;
pDrive->okDma = (pParam->capabilities & 0x0100) ? TRUE : FALSE;
/* find out supported max PIO mode */
pDrive->pioMode = (pParam->pioMode >> 8) & 0x03; /* PIO 0,1,2 */
if (pDrive->pioMode > 2)
pDrive->pioMode = 0;
if ((pDrive->okIordy) && (pParam->valid & 0x02)) /* PIO 3,4 */
{
if (pParam->advancedPio & 0x01)
pDrive->pioMode = 3;
if (pParam->advancedPio & 0x02)
pDrive->pioMode = 4;
}
/* find out supported max DMA mode */
if (pParam->multiDma & 0x04)
pDrive->multiDmaMode = 2;
else if (pParam->multiDma & 0x02)
pDrive->multiDmaMode = 1;
else if (pParam->multiDma & 0x01)
pDrive->multiDmaMode = 0;
else pDrive->multiDmaMode = -1;
/* Is Ultra DMA supported */
if (pParam->valid & 0x04)
{
if (pParam->ultraDma & 0x40)
pDrive->ultraDmaMode = 6;
else if (pParam->ultraDma & 0x20)
pDrive->ultraDmaMode = 5;
else if (pParam->ultraDma & 0x10)
pDrive->ultraDmaMode = 4;
else if (pParam->ultraDma & 0x08)
pDrive->ultraDmaMode = 3;
else if (pParam->ultraDma & 0x04)
pDrive->ultraDmaMode = 2;
else if (pParam->ultraDma & 0x02)
pDrive->ultraDmaMode = 1;
else if (pParam->ultraDma & 0x01)
pDrive->ultraDmaMode = 0;
}
else
pDrive->ultraDmaMode = -1;
if (pDrive->ultraDmaMode == -1 &&
pDrive->multiDmaMode == -1)
pDrive->okDma = FALSE;
else
pDrive->okDma = TRUE;
/* 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;
/*added by youyan 2005-11-19 11:07*/
pDrive->status = ATA_ACTIVE_MODE; /*active mode*/
/*end of added by youyan 2005-11-19 11:07*/
/* add by wangb 2005-11-2 14:43 */
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;
break;
case ATA_PIO_AUTO:
pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
break;
}
if(pDrive->okDma)
switch (configType & ATA_DMA_MODE_MASK)
{
case ATA_DMA_MULTI_0:
pDrive->rwDma = ATA_DMA_MULTI_W_0;
break;
case ATA_DMA_MULTI_1:
pDrive->rwDma = ATA_DMA_MULTI_W_1;
break;
case ATA_DMA_MULTI_2:
pDrive->rwDma = ATA_DMA_MULTI_W_2;
break;
case ATA_DMA_ULTRA_0:
pDrive->rwDma = ATA_DMA_ULTRA_W_0;
break;
case ATA_DMA_ULTRA_1:
pDrive->rwDma = ATA_DMA_ULTRA_W_1;
break;
case ATA_DMA_ULTRA_2:
pDrive->rwDma = ATA_DMA_ULTRA_W_2;
break;
case ATA_DMA_ULTRA_3:
pDrive->rwDma = ATA_DMA_ULTRA_W_3;
break;
case ATA_DMA_ULTRA_4:
pDrive->rwDma = ATA_DMA_ULTRA_W_4;
break;
case ATA_DMA_ULTRA_5:
pDrive->rwDma = ATA_DMA_ULTRA_W_5;
break;
case ATA_DMA_AUTO:
#if 1
if (pDrive->ultraDmaMode != -1)
pDrive->rwDma = ATA_DMA_ULTRA_W_0 + pDrive->ultraDmaMode;
#endif
else if (pDrive->multiDmaMode != -1)
pDrive->rwDma = ATA_DMA_MULTI_W_0 + pDrive->multiDmaMode;
break;
default:
//
// Turn off dma
//
pDrive->okDma = FALSE;
break;
} //end switch
/* end by wangb 2005-11-2 14:44 */
/* set the transfer mode */
if (pDrive->okDma)
{
//logMsg("go here okDma!\n",1,2,3,4,5,6);
ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,pDrive->rwDma);
}
else
{
ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,pDrive->rwMode);
if (pDrive->rwPio == ATA_PIO_MULTI)
{
if (pDrive->okMulti)
(void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,pDrive->multiSecs, 0);
else
pDrive->rwPio = ATA_PIO_SINGLE;
}
}
}/*end of for(driver....*/
pCtrl->installed = TRUE;
#ifdef ATA_DEBUG
printErr ("ataDrv Calling sysAtaInit (if present):\n");
#endif /* ATA_DEBUG */
/* Call system INIT routine to allow proper PIO mode setup */
SYS_ATA_INIT_RTN (ctrl);
#ifdef ATA_DEBUG
printErr ("ataDrv sysAtaInit returned:\n");
#endif /* ATA_DEBUG */
semGive (&pCtrl->muteSem);
}
return (OK);
}
/*******************************************************************************
*
* ataDevCreate - create a device for a ATA/IDE disk
*
* This routine creates a device for a specified ATA/IDE disk.
*
* <drive> is a drive number for the hard drive; it must be 0 or 1.
*
* 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 *ataDevCreate
(
int ctrl,
int drive,
int nBlocks,
int blkOffset
)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
ATA_TYPE *pType = &ataTypes[ctrl][drive];
ATA_DRIVE *pDrive = &pCtrl->drive[drive];
ATA_DEV *pDev;
BLK_DEV *pBlkdev;
int maxBlks;
if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
!ataDrvInstalled || !pCtrl->installed)
return (NULL);
if ((pDev = (ATA_DEV *)malloc(sizeof (ATA_DEV))) == NULL)
return (NULL);
pBlkdev = &pDev->blkDev;
/*
* 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) &&
(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 = TRUE;
pBlkdev->bd_retry = 1;
pBlkdev->bd_mode = O_RDWR;
pBlkdev->bd_readyChanged = TRUE;
pBlkdev->bd_blkRd = ataBlkRd;
pBlkdev->bd_blkWrt = ataBlkWrt;
pBlkdev->bd_ioctl = ataIoctl;
pBlkdev->bd_reset = ataReset;
pBlkdev->bd_statusChk = ataStatus;
pBlkdev->bd_reset = NULL;
pBlkdev->bd_statusChk = NULL;
pDev->ctrl = ctrl;
pDev->drive = drive;
pDev->blkOffset = blkOffset;
return (&pDev->blkDev);
}
/*******************************************************************************
*
* ataRawio - do raw I/O access
*
* This routine is called to perform raw I/O access.
*
* <drive> is a drive number for the hard drive: it must be 0 or 1.
*
* The <pAtaRaw> is a pointer to the structure ATA_RAW which is defined in
* ataDrv.h.
*
* RETURNS:
* OK, or ERROR if the parameters are not valid.
*
*/
STATUS ataRawio
(
int ctrl,
int drive,
ATA_RAW *pAtaRaw
)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
ATA_TYPE *pType = &ataTypes[ctrl][drive];
ATA_DEV ataDev;
BLK_DEV *pBlkdev = &ataDev.blkDev;
UINT startBlk;
if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
!ataDrvInstalled || !pCtrl->installed)
return (ERROR);
if ((pAtaRaw->cylinder >= pType->cylinders) ||
(pAtaRaw->head >= pType->heads) ||
(pAtaRaw->sector > pType->sectors) ||
(pAtaRaw->sector == 0))
return (ERROR);
pBlkdev->bd_nBlocks = pType->cylinders * pType->heads *
pType->sectors;
pBlkdev->bd_bytesPerBlk = pType->bytes;
pBlkdev->bd_blksPerTrack = pType->sectors;
pBlkdev->bd_nHeads = pType->heads;
pBlkdev->bd_removable = FALSE;
pBlkdev->bd_retry = 1;
pBlkdev->bd_mode = O_RDWR;
pBlkdev->bd_readyChanged = TRUE;
pBlkdev->bd_blkRd = ataBlkRd;
pBlkdev->bd_blkWrt = ataBlkWrt;
pBlkdev->bd_ioctl = ataIoctl;
pBlkdev->bd_reset = ataReset;
pBlkdev->bd_statusChk = ataStatus;
ataDev.ctrl = ctrl;
ataDev.drive = drive;
ataDev.blkOffset = 0;
startBlk = pAtaRaw->cylinder * (pType->sectors * pType->heads) +
pAtaRaw->head * pType->sectors + pAtaRaw->sector - 1;
return (ataBlkRW (&ataDev, startBlk, pAtaRaw->nSecs, pAtaRaw->pBuf,
pAtaRaw->direction));
}
/*******************************************************************************
*
* ataBlkRd - read one or more blocks from a ATA/IDE disk
*
* This routine reads one or more blocks from the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the read command didn't succeed.
*/
LOCAL STATUS ataBlkRd
(
ATA_DEV *pDev,
int startBlk,
int nBlks,
char *pBuf
)
{
return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_RDONLY));
}
/*******************************************************************************
*
* ataBlkWrt - write one or more blocks to a ATA/IDE disk
*
* This routine writes one or more blocks to the specified device,
* starting with the specified block number.
*
* If any block offset was specified during ataDevCreate(), it is added
* to <startBlk> before the transfer takes place.
*
* RETURNS: OK, ERROR if the write command didn't succeed.
*/
LOCAL STATUS ataBlkWrt
(
ATA_DEV *pDev,
int startBlk,
int nBlks,
char *pBuf
)
{
return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_WRONLY));
}
/*******************************************************************************
*
* ataReset - reset a ATA/IDE disk controller
*
* This routine resets a ATA/IDE disk controller.
*
* RETURNS: OK, always.
*/
LOCAL STATUS ataReset
(
ATA_DEV *pDev
)
{
ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
if (!pCtrl->installed)
return (ERROR);
semTake (&pCtrl->muteSem, WAIT_FOREVER);
(void) ataInit (pDev->ctrl);
semGive (&pCtrl->muteSem);
return (OK);
}
/*******************************************************************************
*
* ataStatus - check status of a ATA/IDE disk controller
*
* This routine check status of a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the card is removed.
*/
LOCAL STATUS ataStatus
(
ATA_DEV *pDev
)
{
ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
BLK_DEV *pBlkdev = &pDev->blkDev;
if (!pCtrl->installed)
return (ERROR);
if (pCtrl->changed)
{
pBlkdev->bd_readyChanged = TRUE;
pCtrl->changed = FALSE;
}
return (OK);
}
/*******************************************************************************
*
* ataIoctl - do device specific control function
*
* This routine is called when the file system cannot handle an ioctl()
* function.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS ataIoctl
(
ATA_DEV *pDev,
int function,
int arg
)
{
ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
FAST int status = ERROR;
if (!pCtrl->installed)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -