📄 atadrv.c
字号:
ATA_DEBUG_MSG (3, "Enter into ataBlkRW\n", 0, 0, 0, 0, 0, 0); if (!pCtrl->installed) return (ERROR); nSecs = pBlkdev->bd_nBlocks; if ((startBlk + nBlks) > nSecs) { ATA_DEBUG_MSG (1, "startBlk=%d nBlks=%d: 0 - %d\n", startBlk, nBlks, nSecs, 0, 0, 0); return (ERROR); } startBlk += pDev->blkOffset; semTake (&pCtrl->muteSem, WAIT_FOREVER); for (ix = 0; ix < nBlks; ix += nSecs) { if (pDrive->okLba) { head = (startBlk & 0x0f000000) >> 24; cylinder = (startBlk & 0x00ffff00) >> 8; sector = (startBlk & 0x000000ff); } else { cylinder = startBlk / (pType->sectors * pType->heads); sector = startBlk % (pType->sectors * pType->heads); head = sector / pType->sectors; sector = sector % pType->sectors + 1; } nSecs = min (nBlks - ix, ATA_MAX_RW_SECTORS); retryRW1 = 0; retryRW0 = 0; if((ourRwMode == ATA_MDMA) ||(ourRwMode == ATA_UDMA)) { while (ataDmaRW(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; } } } else { 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 ataBestcommIntr ( int ctrl ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_DEBUG_MSG (3, "Enter into ataBestcommIntr\n", 0, 0, 0, 0, 0, 0); pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status); if(TaskIntStatus(TaskAtaId) == TaskAtaId) { TaskIntClear(TaskAtaId); intDisable(INUM_SDMA_TASK5);/*Disable ints*/ if(rtswitch == O_RDONLY) { ATA_IO_BYTE_WRITE((UINT32)ATA_DMAMODE_REG, 0); semGive (&pCtrl->rdsyncSem); } } pCtrl->intCount++; }/********************************************************************************* ataIntr - ATA/IDE controller interrupt handler.** RETURNS: N/A*/LOCAL void ataIntr ( int ctrl ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_DEBUG_MSG (3, "Enter into ataIntr\n", 0, 0, 0, 0, 0, 0); pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status); if(rtswitch == O_WRONLY) { ATA_IO_BYTE_WRITE((UINT32)ATA_DMAMODE_REG, 0); } semGive (&pCtrl->syncSem); pCtrl->intCount++; }/********************************************************************************* ataWdog - ATA/IDE controller watchdog handler.** RETURNS: N/A*/LOCAL void ataWdog ( int ctrl ) { ATA_CTRL *pCtrl = &ataCtrl[ctrl]; ATA_DEBUG_MSG (3, "Enter into ataWdog\n", 0, 0, 0, 0, 0, 0); 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 (1, "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 (1, "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 (1, "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); semBInit(&pCtrl->rdsyncSem, SEM_Q_FIFO, SEM_EMPTY); ATA_DEBUG_MSG (3, "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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -