📄 ide.c
字号:
int nTimeout; BYTE bStatus; BYTE bDummy; nError = IDE_OK; if (WaitNotBusy(CONTROLLERTIMEOUT) == IDE_OK) { IDEOut(DISK_HEAD_REG, 0xA0 + (bDevice << 4)); Wait400ns(); nError = WaitNotBusy(CONTROLLERTIMEOUT); } else { nError = IDE_BUSY; } if (nError != IDE_OK) { // // Test for special case, data available. // If data available, read the data!! // bStatus = IDEIn(STATUS_REG); if (bStatus & STATUS_DATA_REQUEST) { nTimeout = 512; while ((bStatus & STATUS_DATA_REQUEST) && (nTimeout)) { bDummy = IDEIn(DATA_READ_REG_LOW); bDummy = IDEIn(DATA_READ_REG_LOW); bStatus = IDEIn(STATUS_REG); nTimeout--; } } } return (nError);}#if (IDE_SUPPORT_ATAPI == 1)/************************************************************//* ATAPISendCommand *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int ATAPISendCommand(LPDRIVE pDrive, BYTE * pSectorBuffer, WORD * pReadCount){ int nError; BYTE bStatus; BYTE bDevice; WORD x, y; BYTE bDummy; WORD wSectorSize; nError = IDE_ERROR; bDummy = 0; bDevice = pDrive->bDevice; wSectorSize = pDrive->wSectorSize; *pReadCount = 0; if (SelectDevice(bDevice) == IDE_OK) { ClearEvent(&hIDEEvent); if (WaitNotBusy(ATAPITIMEOUT) == IDE_OK) { IDEOut(FEATURE_REG, 0x00); IDEOut(SECTOR_COUNT_REG, 0x00); IDEOut(SECTOR_REG, 0x00); IDEOut(CYLINDER_LOW_REG, LOBYTE(wSectorSize)); IDEOut(CYLINDER_HIGH_REG, HIBYTE(wSectorSize)); IDEOut(COMMAND_REG, 0xA0); if (pDrive->wFlags & IDE_SUPPORT_INTRQ_PACKET) { nError = WaitForInterrupt(ATAPITIMEOUT); if (nError == IDE_OK) { ClearEvent(&hIDEEvent); } } else { nError = WaitDRQ(ATAPITIMEOUT); } if (nError == IDE_OK) { for (x = 0; x < 12; x = x + 2) { IDEOut(DATA_WRITE_REG_HIGH, aATAPICmd[x + 1]); IDEOut(DATA_WRITE_REG_LOW, aATAPICmd[x]); } if (WaitForInterrupt(ATAPITIMEOUT) == IDE_OK) { if (gbIntStatus & STATUS_ERROR) { nError = IDE_ERROR; } else { nError = IDE_OK; if (gbIntStatus & STATUS_DATA_REQUEST) { Wait400ns(); y = IDEIn(CYLINDER_HIGH_REG) << 8; y |= IDEIn(CYLINDER_LOW_REG); if (y > wSectorSize) { y = wSectorSize; } if (pSectorBuffer != NULL) { for (x = 0; x < y; x = x + 2) { pSectorBuffer[x] = pIDE[DATA_READ_REG_LOW]; pSectorBuffer[x + 1] = pIDE[DATA_READ_REG_HIGH]; } } else { for (x = 0; x < y; x = x + 2) { bDummy += pIDE[DATA_READ_REG_LOW]; bDummy += pIDE[DATA_READ_REG_HIGH]; } } *pReadCount = y; bStatus = IDEIn(STATUS_REG); } /* endif STATUS_DATA_REQUEST */ } /* endif STATUS_ERROR */ } /* endif WaitForInterrupt(ATAPITIMEOUT) */ } /* endif (WaitDRQ(ATAPITIMEOUT) */ } /* endif WaitNotBusy(ATAPITIMEOUT) */ } /* endif SelectDevice(bDevice) */ return (nError);}/************************************************************//* ATAPIGetTotalSectors *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int ATAPIGetTotalSectors(LPDRIVE pDrive, BYTE * pSectorBuffer, DWORD * pMaxSectors){ int nError; WORD wReadCount; WORD wErrorCount; DWORD dwValue; nError = IDE_OK; *pMaxSectors = 0; wErrorCount = 4; while (wErrorCount) { ATAPI_CMD(ATAPI_CMD_READ_CAPACITY); nError = ATAPISendCommand(pDrive, pSectorBuffer, &wReadCount); if ((nError == IDE_OK) && (wReadCount == 8)) { dwValue = pSectorBuffer[0]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[1]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[2]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[3]; *pMaxSectors = dwValue; // // Get SectorSize // dwValue = pSectorBuffer[4]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[5]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[6]; dwValue = dwValue << 8; dwValue |= pSectorBuffer[7]; if (dwValue > ATAPI_SECTOR_SIZE) { dwValue = ATAPI_SECTOR_SIZE; } pDrive->wSectorSize = (WORD) (dwValue & 0x0000FFFF); break; } wErrorCount--; NutSleep(2000); } return (nError);}/************************************************************//* GetDeviceInfoPacket *//* *//* PIO data in command protocol (see ATAPI-4 r17 p224 9.7) *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int GetDeviceInfoPacket(LPDRIVE pDrive, BYTE * pSectorBuffer){ WORD i; int nError; BYTE bStatus; BYTE bErrorReg; BYTE bDevice; WORD wConfig; DWORD dwTotalSectors; nError = IDE_ERROR; bDevice = pDrive->bDevice; if (SelectDevice(bDevice) == IDE_OK) { ClearEvent(&hIDEEvent); IDEOut(COMMAND_REG, COMMAND_DEVICE_INFO_P); if (WaitForInterrupt(DISKTIMEOUT) == IDE_OK) { if (gbIntStatus & STATUS_DATA_REQUEST) { for (i = 0; i < IDE_SECTOR_SIZE; i = i + 2) { pSectorBuffer[i] = pIDE[DATA_READ_REG_LOW]; if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) { pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_LOW]; } else { pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_HIGH]; } } // // Status register is read to clear // pending interrupts. // bStatus = IDEIn(STATUS_REG); pDrive->wFlags = 0; wConfig = *(WORD *) & pSectorBuffer[0]; if ((wConfig & ATAPI_CFG_INTRQ) == ATAPI_USE_INTRQ) { pDrive->wFlags |= IDE_SUPPORT_INTRQ_PACKET; } if ((wConfig & ATAPI_CFG_DEVICE) == ATAPI_IS_DIRECT_ACCESS) { pDrive->wFlags |= IDE_ZIP_DEVICE; } if ((wConfig & ATAPI_CFG_DEVICE) == ATAPI_IS_CDROM) { pDrive->wFlags |= (IDE_READ_ONLY | IDE_CDROM_DEVICE); } if ((wConfig & ATAPI_CFG_ATAPI) == ATAPI_IS_PACKET) { pDrive->wFlags |= IDE_SUPPORT_PACKET; } if ((wConfig & ATAPI_CFG_12_BYTE_MSK) == ATAPI_IS_12_BYTE) { pDrive->wFlags |= IDE_READY; nError = ATAPIGetTotalSectors(pDrive, pSectorBuffer, &dwTotalSectors); if (nError == IDE_OK) { pDrive->dwTotalSectors = dwTotalSectors; // // ModeSense // ATAPI_CMD(0x5A); aATAPICmd[2] = 0x2A; aATAPICmd[7] = 0x08; aATAPICmd[8] = 0x00; ATAPISendCommand(pDrive, pSectorBuffer, &i); // // Set Speed to 150KByte // IDEATAPISetCDSpeed(bDevice, 150); } else { pDrive->dwTotalSectors = 0; } //ATAPITest(pDrive, pSectorBuffer); } } if (gbIntStatus & STATUS_ERROR) { bErrorReg = IDEIn(ERROR_REG); } } } return (nError);}#endif/************************************************************//* GetDeviceInfo *//* *//* PIO data in command protocol (see ATAPI-4 r17 p224 9.7) *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int GetDeviceInfo(LPDRIVE pDrive, BYTE * pSectorBuffer){ WORD i; int nError; BYTE bStatus; BYTE bErrorReg; BYTE bDevice; IDEDEVICEINFO *pInfo; nError = IDE_ERROR; bDevice = pDrive->bDevice; if (SelectDevice(bDevice) == IDE_OK) { ClearEvent(&hIDEEvent);#if 0 IDEOut(FEATURE_REG, 0); IDEOut(SECTOR_COUNT_REG, 1); IDEOut(SECTOR_REG, 0); IDEOut(CYLINDER_LOW_REG, 0); IDEOut(CYLINDER_HIGH_REG, 0);#endif IDEOut(COMMAND_REG, COMMAND_DEVICE_INFO); if (WaitForInterrupt(DISKTIMEOUT) == IDE_OK) { if (gbIntStatus & STATUS_DATA_REQUEST) { for (i = 0; i < IDE_SECTOR_SIZE; i = i + 2) { pSectorBuffer[i] = pIDE[DATA_READ_REG_LOW]; if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) { pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_LOW]; } else { pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_HIGH]; } } // // Status register is read to clear // pending interrupts. // bStatus = IDEIn(STATUS_REG); pInfo = (IDEDEVICEINFO *) pSectorBuffer;#if (IDE_SUPPORT_CHS == 1) pDrive->wCylinders = (WORD) pInfo->Cylinders; pDrive->wHeads = (BYTE) pInfo->Heads; pDrive->wSectorsPerTrack = (BYTE) pInfo->SectorsPerTrack; pDrive->dwOneSide = pDrive->wCylinders * pDrive->wSectorsPerTrack;#endif if (pInfo->LBASectors > 0) { pDrive->wFlags = IDE_READY | IDE_SUPPORT_LBA; pDrive->dwTotalSectors = pInfo->LBASectors; } else {#if (IDE_SUPPORT_CHS == 1) pDrive->wFlags = IDE_READY; pDrive->dwTotalSectors = pInfo->Cylinders; pDrive->dwTotalSectors *= pInfo->Heads; pDrive->dwTotalSectors *= pInfo->SectorsPerTrack;#endif } nError = IDE_OK; } if (gbIntStatus & STATUS_ERROR) { bErrorReg = IDEIn(ERROR_REG); } } } return (nError);}/************************************************************//* IsPacketDevice *//* *//* Check Command block register, *//* see page 210, 9.1 Signature and persistence *//* *//* Return: TRUE, FALSE *//************************************************************/#if (IDE_SUPPORT_ATAPI == 1)static int IsPacketDevice(void){ int nPacketDevice; BYTE bSectorCount; BYTE bSectorNumber; BYTE bCylinderLow; BYTE bCylinderHigh; nPacketDevice = FALSE; bSectorCount = IDEIn(SECTOR_COUNT_REG); bSectorNumber = IDEIn(SECTOR_REG); bCylinderLow = IDEIn(CYLINDER_LOW_REG); bCylinderHigh = IDEIn(CYLINDER_HIGH_REG); if ((bCylinderLow == 0x14) && (bCylinderHigh == 0xEB)) { nPacketDevice = TRUE; } return (nPacketDevice);}#elsestatic int IsPacketDevice(void){ return (FALSE);}#endif/************************************************************//* DeviceDiag *//* *//* NON-data command protocol (see ATAPI-4 r17 p231 9.9) *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int DeviceDiag(LPDRIVE pDrive){ int nError; BYTE bResult; nError = IDE_ERROR; if (SelectDevice(0) == IDE_OK) {#if 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -