📄 nwatadrv.c
字号:
return (ERROR);
semTake (&pCtrl->muteSem, WAIT_FOREVER);
switch (function)
{
case FIODISKFORMAT:
/*(void) errnoSet (S_ioLib_UNKNOWN_REQUEST);*/
break;
default:
/*(void) errnoSet (S_ioLib_UNKNOWN_REQUEST);*/
break;
}
semGive (&pCtrl->muteSem);
return (status);
}
/*******************************************************************************
*
* ataBlkRW - read or write sectors to a ATA/IDE disk.
*
* Read or write sectors to a ATA/IDE disk.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/
LOCAL STATUS ataBlkRW(ATA_DEV *pDev,int startBlk,int nBlks,char *pBuf,int direction)
{
ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
ATA_DRIVE *pDrive = &pCtrl->drive[pDev->drive];
BLK_DEV *pBlkdev = &pDev->blkDev;
int status = ERROR;
int retryRW0 = 0;
int retryRW1 = 0;
int retrySeek = 0;
int cylinder;
int head;
int sector;
int nSecs;
int ix;
/* sanity check */
if (!pCtrl->installed)
return (ERROR);
nSecs = ataLbaTotalSecs[pDev->ctrl][pDev->drive];//pBlkdev->bd_nBlocks;
// printErr ("startBlk=%d nBlks=%d: nSecs=%d\n", startBlk, nBlks, nSecs);
if ((startBlk + nBlks) > nSecs)
{
//#ifdef ATA_DEBUG
printf("startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, nSecs);
//#endif /* ATA_DEBUG */
return (ERROR);
}
startBlk += pDev->blkOffset;
semTake (&pCtrl->muteSem, WAIT_FOREVER);
for (ix = 0; ix < nBlks; ix += nSecs)
{
if (pDrive->okLba)
{
head = (startBlk & 0xff000000) >> 24;//modify from 0x0f000000 to 0xff000000 2005-6-22 16:25 by wb
cylinder = (startBlk & 0x00ffff00) >> 8;
sector = (startBlk & 0x000000ff);
}
else
{
cylinder = startBlk / (pBlkdev->bd_blksPerTrack * pBlkdev->bd_nHeads);
sector = startBlk % (pBlkdev->bd_blksPerTrack * pBlkdev->bd_nHeads);
head = sector / pBlkdev->bd_blksPerTrack;
sector = sector % pBlkdev->bd_blksPerTrack + 1;
}
nSecs = min (nBlks - ix, ATA_MAX_RW_SECTORS);
retryRW1 = 3;
retryRW0 = 3;
while (ataRW(pDev->ctrl, pDev->drive, cylinder, head, sector,
pBuf, nSecs, direction) != OK)
{
if (++retryRW0 > ataRetry)
{
(void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_RECALIB, 0,0);
if (++retryRW1 > ataRetry)
goto done;
retrySeek = 0;
while (ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_SEEK, cylinder,head) != OK)
if (++retrySeek > ataRetry)
goto done;
retryRW0 = 0;
}
}
startBlk += nSecs;
pBuf += pBlkdev->bd_bytesPerBlk * nSecs;
}
status = OK;
done:
if (status == ERROR)
/*(void)errnoSet (S_ioLib_DEVICE_ERROR);*/
semGive (&pCtrl->muteSem);
return (status);
}
/*******************************************************************************
*
* ataIntr - ATA/IDE controller interrupt handler.
*
* RETURNS: N/A
*/
LOCAL void ataIntr(int ctrl)
{
ATA_CTRL *pCtrl;
char atpStatus =0;
unsigned int isr;
KS8695P_REG_READ (REG_INT_STATUS, isr);
/* if not ours, simply return */
if ((isr & REG_INT_EXTI1) == 0)
return ;
//logMsg("go here intr wangb !\n",1,2,3,4,5,6);
/* disable interrupt first */
KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_EXTI1);
/* ACK */
KS8695P_REG_WRITE(REG_INT_STATUS, REG_INT_EXTI1);
pCtrl = &ataCtrl[ctrl];
//pCtrl->intCount++;
//pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
/*
atpStatus = ATA_IO_BYTE_READ( busMasterRegs[ctrl] + BM_STATUS_REG);
if (atpStatus & 0x4)
ATA_IO_BYTE_WRITE(busMasterRegs[ctrl]+BM_STATUS_REG,atpStatus);
*/
semGive (&pCtrl->syncSem);
KS8695P_REG_BIT_SET (REG_INT_ENABLE, REG_INT_EXTI1);
}
/*******************************************************************************
*
* ataWdog - ATA/IDE controller watchdog handler.
*
* RETURNS: N/A
*/
LOCAL void ataWdog
(
int ctrl
)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
pCtrl->wdgOkay = FALSE;
}
/*******************************************************************************
*
* ataWait - wait the drive ready
*
* Wait the drive ready
*
* RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.
*/
LOCAL void ataWait(int ctrl,int request)
{
unsigned char tempData =0;
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
#ifdef ATA_DEBUG
printErr ("ataWait: ctrl=%d request=0x%x\n", ctrl, request);
#endif /* ATA_DEBUG */
switch (request)
{
case ATA_STAT_READY:
wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
(FUNCPTR)ataWdog, ctrl);
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
(pCtrl->wdgOkay))
;
tempData = ATA_IO_BYTE_READ (pCtrl->aStatus);
while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
&& (pCtrl->wdgOkay))
;
wdCancel (pCtrl->wdgId);
if (!pCtrl->wdgOkay)
{
pCtrl->wdgOkay = TRUE;
(void) ataInit (ctrl);
}
break;
case ATA_STAT_BUSY:
while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)
;
break;
case ATA_STAT_DRQ:
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)
;
break;
case ATA_STAT_SEEKCMPLT:
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) == 0)
;
break;
}
#ifdef ATA_DEBUG
printErr ("ataWait end:\n");
#endif /* ATA_DEBUG */
}
/*******************************************************************************
*
* ataInit - init a ATA/IDE disk controller
*
* This routine initializes a ATA/IDE disk controller.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/
LOCAL STATUS ataInit
(
int ctrl
)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
int ix;
#ifdef ATA_DEBUG
printErr ("ataInit: ctrl=%d\n", ctrl);
#endif /* ATA_DEBUG */
/*del by wangb 2005-11-2 14:57
ATA_IO_BYTE_WRITE (pCtrl->dControl,
ATA_CTL_4BIT | ATA_CTL_RST | ATA_CTL_IDS);
for (ix = 0; ix < 100; ix++)
ideDelayFun ();
ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT | ATA_CTL_IDS);
for (ix = 0; ix < 100; ix++)
ideDelayFun ();*/
/* add by wangb 2005-11-2 14:57 */
ATA_IO_BYTE_WRITE (pCtrl->dControl,
ATA_CTL_RST | ATA_CTL_IDS);
for (ix = 0; ix < 100; ix++)
ideDelayFun ();
ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_IDS);
for (ix = 0; ix < 100; ix++)
ideDelayFun ();
/* end by wangb 2005-11-2 14:57 */
pCtrl->wdgOkay = TRUE;
/* start the ata watchdog */
wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
(FUNCPTR)ataWdog, ctrl);
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
(pCtrl->wdgOkay))
;
// ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
ATA_IO_BYTE_WRITE (pCtrl->dControl, 0);
for (ix = 0; ix < 100; ix++)
ideDelayFun ();
while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) &&
(pCtrl->wdgOkay))
;
wdCancel (pCtrl->wdgId);
if (!pCtrl->wdgOkay)
{
#ifdef ATA_DEBUG
printErr ("ataInit error:\n");
#endif /* ATA_DEBUG */
pCtrl->wdgOkay = TRUE;
return (ERROR);
}
#ifdef ATA_DEBUG
printErr ("ataInit Calling sysAtaInit (if present):\n");
#endif /* ATA_DEBUG */
/* Call out to bsp specific setup routine */
SYS_ATA_INIT_RTN (ctrl);
#ifdef ATA_DEBUG
printErr ("ataInit sysAtaInit returned:\n");
#endif /* ATA_DEBUG */
#ifdef ATA_DEBUG
printErr ("ataInit end:\n");
#endif /* ATA_DEBUG */
return (OK);
}
/*******************************************************************************
*
* ataCmd - 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 ataCmd(int ctrl,int drive,int cmd,int arg0,int arg1)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
ATA_TYPE *pType = &ataTypes[ctrl][drive];
BOOL retry = TRUE;
int retryCount = 0;
int semStatus;
#ifdef ATA_DEBUG
printErr ("ataCmd: ctrl=%d drive=%d cmd=0x%x\n", ctrl, drive, cmd);
#endif /* ATA_DEBUG */
while (retry)
{
ataWait (ctrl, ATA_STAT_READY);
ATA_IO_BYTE_WRITE (pCtrl->sdh, (drive << 4));
taskDelay(0);
ataWait (ctrl, ATA_STAT_READY);
switch (cmd)
{
case ATA_CMD_DIAGNOSE:
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
break;
case ATA_CMD_INITP:
ATA_IO_BYTE_WRITE (pCtrl->cylLo, pType->cylinders);
ATA_IO_BYTE_WRITE (pCtrl->cylHi, pType->cylinders >> 8);
ATA_IO_BYTE_WRITE (pCtrl->seccnt, pType->sectors);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |
((pType->heads - 1) & 0x0f));
break;
case ATA_CMD_RECALIB:
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
break;
case ATA_CMD_SEEK:
ATA_IO_BYTE_WRITE (pCtrl->cylLo, arg0);
ATA_IO_BYTE_WRITE (pCtrl->cylHi, arg0>>8);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |
(arg1 & 0xf));
break;
case ATA_CMD_SET_FEATURE:
ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg1);
ATA_IO_BYTE_WRITE (pCtrl->feature, arg0);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
break;
case ATA_CMD_SET_MULTI:
ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg0);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
break;
}
ATA_IO_BYTE_WRITE (pCtrl->command, cmd);
semStatus = semTake (&pCtrl->syncSem,
sysClkRateGet() * pCtrl->semTimeout);
pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);//add by wangb 2005-11-8 8:56
if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
{
#ifdef ATA_DEBUG
int error = ATA_IO_BYTE_READ(pCtrl->error);
printErr ("ataCmd err: status=0x%x semStatus=%d err=0x%x\n",
pCtrl->intStatus, semStatus, error);
#endif /* ATA_DEBUG */
if (++retryCount > ataRetry)
return (ERROR);
}
else
retry = FALSE;
}
switch (cmd)
{
case ATA_CMD_SEEK:
ataWait (ctrl, ATA_STAT_SEEKCMPLT);
break;
}
#ifdef ATA_DEBUG
printErr ("ataCmd end:\n");
#endif /* ATA_DEBUG */
return (OK);
}
/*******************************************************************************
*
* ataPread - Read drive parameters
*
* Read drive parameters.
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/
LOCAL STATUS ataPread(int ctrl,int drive,void *buffer)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
BOOL retry = TRUE;
int retryCount = 0;
int semStatus;
#ifdef ATA_DEBUG
printErr ("ataPread: ctrl=%d drive=%d\n", ctrl, drive);
printErr ("drive << 4,0x%x\n",(drive<<4));
#endif /* ATA_DEBUG */
/*by youyan 2005-11-21 10:32
while (retry)
{
ataWait(ctrl, ATA_STAT_READY); */
ATA_IO_BYTE_WRITE (pCtrl->sdh, (drive << 4));
ataWait (ctrl, ATA_STAT_READY);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);
semStatus = semTake (&pCtrl->syncSem,sysClkRateGet() * pCtrl->semTimeout);
pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);//add by wangb 2005-11-8 8:56
if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
{
#ifdef ATA_DEBUG
int error = ATA_IO_BYTE_READ (pCtrl->error);
int status = ATA_IO_BYTE_READ (pCtrl->aStatus);
printErr ("ataPread err: stat=0x%x 0x%x semStatus=%d err=0x%x\n",
pCtrl->intStatus, status, semStatus, error);
#endif /* ATA_DEBUG */
/*by youyan2005-11-21 10:32
if (++retryCount > ataRetry)
*/
return (ERROR);
}
else
retry = FALSE;
/* }*/
ataWait (ctrl, ATA_STAT_DRQ);
ATA_IO_NWORD_READ_SWAP (pCtrl->data, (short *)buffer, 256);
#ifdef ATA_DEBUG
printErr ("ataPread end:\n");
#endif /* ATA_DEBUG */
return (OK);
}
/*******************************************************************************
*
* ataRW - read/write a number of sectors on the current track
*
* Read/write a number of sectors on the current track
*
* RETURNS: OK, ERROR if the command didn't succeed.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -