📄 atadrv.c
字号:
{
if (++retryRW0 > ataRetry)
{
(void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_RECALIB, NULL,
NULL);
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:
#ifndef BUILD_BOOTROM
if (status == ERROR)
(void)errnoSet (S_ioLib_DEVICE_ERROR);
#endif
semGive (&ataCtrl[0].muteSem);
return (status);
} /* ataBlkRW */
/*******************************************************************************
*
* ataIntr - ATA/IDE controller interrupt handler.
*
* RETURNS: N/A
*/
LOCAL void ataIntr
(
int ctrl
)
{
ATA_CTRL *pCtrl;
pCtrl = &ataCtrl[0];
if (pCtrl->installed) {
ATA_INTR_MSG ("ataIntr %d miriam\n", 0, 0, 0, 0, 0, 0);
pCtrl->intCount++;
pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
}
pCtrl = &ataCtrl[1];
if (pCtrl->installed) {
ATA_INTR_MSG ("ataIntr %d miriam\n", 1, 0, 0, 0, 0, 0);
pCtrl->intCount++;
pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
}
semGive (&ataCtrl[0].syncSem);
} /* ataIntr */
/*******************************************************************************
*
* ataWdog - ATA/IDE controller watchdog handler.
*
* RETURNS: N/A
*/
LOCAL void ataWdog
(
int ctrl
)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
pCtrl->wdgOkay = FALSE;
} /* ataWdog */
/*******************************************************************************
*
* 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 STATUS ataWait
(
int ctrl,
int drive,
int request,
BOOL reset
)
{
ATA_CTRL * pCtrl = &ataCtrl[ctrl];
ATA_DRIVE * pDrive;
ATA_DEBUG_MSG (3, "ataWait: ctrl=%d request=0x%x\n", ctrl, request, 0, 0,
0, 0);
pDrive = &pCtrl->drive[drive];
switch (request)
{
case ATA_STAT_READY:
ATA_DEBUG_MSG (3, "ataWait:0x%x - case ATA_STAT_READY-wdStart\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
(FUNCPTR)ataWdog, ctrl);
ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_BUSY\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
(pCtrl->wdgOkay))
;
ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_READY\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
&& (pCtrl->wdgOkay))
;
ATA_DEBUG_MSG (3, "ataWait:0x%x - ATA_STAT_DRQ\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
(pCtrl->wdgOkay))
;
ATA_DEBUG_MSG (3, "ataWait:0x%x - wdCancel\n",hmpv_read_fcnt(), 0, 0, 0, 0, 0);
wdCancel (pCtrl->wdgId);
if (!pCtrl->wdgOkay)
{
pCtrl->wdgOkay = TRUE;
if (reset == TRUE)
(void) pDrive->Reset (ctrl, drive);
return (ERROR);
}
break;
case ATA_STAT_ACCESS:
wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
(FUNCPTR)ataWdog, ctrl);
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
(pCtrl->wdgOkay))
;
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
(pCtrl->wdgOkay))
;
wdCancel (pCtrl->wdgId);
if (!pCtrl->wdgOkay)
{
pCtrl->wdgOkay = TRUE;
if (reset == TRUE)
(void) pDrive->Reset (ctrl, drive);
return (ERROR);
}
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;
case ATA_STAT_DMRD:
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DMRD)
== 0)
;
break;
}
ATA_DEBUG_MSG (3, "ataWait end:\n", 0, 0, 0, 0, 0, 0);
return (OK);
} /* ataWait */
/*******************************************************************************
*
* 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,
int drive
)
{
u_long retaddr = hmpv_return_address();
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
int ix;
ATA_DEBUG_MSG (1, "ataInit:%d/%d from %p\n", ctrl, drive, retaddr, 0, 0, 0);
/* Set reset bit */
#if 1
ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT | ATA_CTL_RST);
#else
ATA_IO_BYTE_WRITE (pCtrl->dControl,ATA_CTL_RST);
#endif
// for (ix = 0; ix < 20; ix++) /* >= 5 mks */
//
// ATA_WAIT_STATUS;
/*wait 5usec */
ataWaitStatus(5000);
/* Clear reset bit */
#if 1
ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
#else
ATA_IO_BYTE_WRITE (pCtrl->dControl, 0);
#endif
// for (ix = 0; ix < 5000; ix++) /* 2 ms */
// ATA_WAIT_STATUS;
ataWaitStatus(2000000);
pCtrl->wdgOkay = TRUE;
/* Start the ATA watchdog */
wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
(FUNCPTR)ataWdog, ctrl);
/* Wait for BUSY bit to be cleared */
while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
(pCtrl->wdgOkay))
;
/* Stop the ATA watchdog */
wdCancel (pCtrl->wdgId);
if (!pCtrl->wdgOkay)
{
ATA_DEBUG_MSG (1, "ataInit error:\n", 0, 0, 0, 0, 0, 0);
pCtrl->wdgOkay = TRUE;
return (ERROR);
}
/* The following allow to recover after accidental interrupt */
if (semTake (&ataCtrl[0].syncSem, NO_WAIT) == OK)
{
ATA_DEBUG_MSG (1, "ataInit%d/%d: WARNING: interrupt cleared\n",
ctrl, drive, 0, 0, 0, 0);
}
else
{
ATA_DEBUG_MSG (2, "ataInit%d/%d: Ok\n", ctrl, drive, 0, 0, 0, 0);
}
//ATA_DEBUG_MSG (3, "ataInit Calling sysAtaInit (if present):\n", 0, 0, 0, 0, 0, 0);
/* Call out to bsp specific setup routine */
//SYS_ATA_INIT_RTN (ctrl);
//ATA_DEBUG_MSG (3, "ataInit sysAtaInit returned\n", 0, 0, 0, 0, 0, 0);
ATA_DEBUG_MSG (2, "ataInit end\n", 0, 0, 0, 0, 0, 0);
return (OK);
} /* ataInit */
/*******************************************************************************
*
* 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;
ATA_DEBUG_MSG (1, "ataCmd%d/%d: cmd=0x%x 0x%x 0x%x\n", ctrl, drive, cmd, arg0, arg1,
0);
while (retry)
{
ataWait (ctrl,drive, ATA_STAT_READY, TRUE);
switch (cmd)
{
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 (&ataCtrl[0].syncSem,
sysClkRateGet() * pCtrl->semTimeout);
if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
{
ATA_DEBUG_MSG (1, "ataCmd%d/%d: ERROR: cmd=0x%x status=0x%x "
"semStatus=%d err=0x%x\n", ctrl, drive, cmd,
pCtrl->intStatus, semStatus,
ATA_IO_BYTE_READ(pCtrl->error));
if (++retryCount > ataRetry)
return (ERROR);
}
else
retry = FALSE;
}
switch (cmd)
{
case ATA_CMD_SEEK:
ataWait (ctrl,drive, ATA_STAT_SEEKCMPLT, FALSE);
break;
}
ATA_DEBUG_MSG (2, "ataCmd%d/%d: Ok\n", ctrl, drive, 0, 0, 0, 0);
return (OK);
} /* ataCmd */
/*******************************************************************************
*
* 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;
ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d\n", ctrl, drive, 0, 0, 0, 0);
while (retry)
{
ataWait (ctrl,drive, ATA_STAT_READY, TRUE);
ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 1\n", ctrl, drive, 0, 0, 0, 0);
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 2\n", ctrl, drive, 0, 0, 0, 0);
ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);
semStatus = semTake (&ataCtrl[0].syncSem,
sysClkRateGet() * pCtrl->semTimeout);
if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
{
ATA_DEBUG_MSG (1, "ataPread%d/%d - err: status=0x%x intStatus=0x%x "
"error=0x%x semStatus=%d\n", ctrl, drive,
ATA_IO_BYTE_READ (pCtrl->aStatus), pCtrl->intStatus,
ATA_IO_BYTE_READ (pCtrl->error), semStatus);
if (++retryCount > ataRetry)
return (ERROR);
}
else
retry = FALSE;
}
ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d mark 3\n", ctrl, drive, 0, 0, 0, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -