📄 m5200atadrv.c
字号:
LOCAL void ataIntr ( int ctrl ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; pCtrl->intCount++; pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status); semGive (&pCtrl->syncSem); }/********************************************************************************* 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 ATA/ATAPI 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 ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_DEBUG_MSG (3, "ataWait: ctrl=%d request=0x%x\n", ctrl, request, 0, 0, 0, 0); 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)) ; 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, 0); } 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; } ATA_DEBUG_MSG (3, "ataWait end:\n", 0, 0, 0, 0, 0, 0); }/********************************************************************************* ataPiWait - wait the ATAPI drive ready** Wait the drive ready** RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.*/LOCAL STATUS ataPiWait ( int ctrl, int request, BOOL reset ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_DRIVE *pDrive; int drive; ATA_DEBUG_MSG (3, "ataPiWait: ctrl=%d request=0x%x\n", ctrl, request, 0, 0, 0, 0); drive = (ATA_IO_BYTE_READ (pCtrl->sdh) >> 4) & 1; pDrive = &pCtrl->drive[drive]; 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)) ; while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) && (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_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; } ATA_DEBUG_MSG (3, "ataPiWait end:\n", 0, 0, 0, 0, 0, 0); return (OK); } /* ataPiWait *//********************************************************************************* 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 dev ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; int ix; ATA_DEBUG_MSG (2, "ataInit: ctrl=%d\n", ctrl, 0, 0, 0, 0, 0); ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT | ATA_CTL_RST); for (ix = 0; ix < 100; ix++) sysDelay (); ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT); for (ix = 0; ix < 100; ix++) sysDelay (); 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); for (ix = 0; ix < 100; ix++) sysDelay (); while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) && (pCtrl->wdgOkay)) ; wdCancel (pCtrl->wdgId); if (!pCtrl->wdgOkay) { ATA_DEBUG_MSG (1, "ataInit error:\n", 0, 0, 0, 0, 0, 0); pCtrl->wdgOkay = TRUE; return (ERROR); } 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); /* * The following allows recovery after an interrupt * caused by drive software reset */ semBInit(&pCtrl->syncSem, SEM_Q_FIFO, SEM_EMPTY); ATA_DEBUG_MSG (2, "ataInit end\n", 0, 0, 0, 0, 0, 0); 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; ATA_DEBUG_MSG (2, "ataCmd%d/%d: cmd=0x%x\n", ctrl, drive, cmd, arg0, arg1, 0); while (retry) { 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); if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR)) { ATA_DEBUG_MSG (1, "ataCmd err: status=0x%x semStatus=%d err=0x%x\n", pCtrl->intStatus, semStatus, ATA_IO_BYTE_READ (pCtrl->error), 0, 0, 0); if (++retryCount > ataRetry) return (ERROR); } else retry = FALSE; } switch (cmd) { case ATA_CMD_SEEK: ataWait (ctrl, ATA_STAT_SEEKCMPLT); break; } ATA_DEBUG_MSG (2, "ataCmd end - ctrl %d, drive %d: Ok\n", ctrl, drive, 0, 0, 0, 0); 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; ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%d\n", ctrl, drive, 0, 0, 0, 0); while (retry) { 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); 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; } ataWait (ctrl, ATA_STAT_DRQ); ATA_IO_NWORD_READ_SWAP (pCtrl->data, buffer, 256); ATA_DEBUG_MSG (2, "ataPread end:\n", 0, 0, 0, 0, 0, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -