/* This function returns the Error Register value*/ BYTE ReadErrorRegister(BYTE DeviceController) { BYTE Status = InPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_STATUS); if ((Status & 0x80) == 0 && (Status & 0x1)) //busy bit=0 and err bit=1 { Status = InPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_ERROR); return Status; } else return 0; }
/* --------------------------------------------------------------------- */ UCHAR XGINew_GetReg1( USHORT port , USHORT index ) { UCHAR data ; #ifdef LINUX_XF86 OutPortByte( ( PUCHAR )(ULONG)port , index ) ; data = InPortByte( ( PUCHAR )(ULONG)port + 1 ) ; #else OutPortByte( ( PUCHAR )port , index ) ; data = InPortByte( ( PUCHAR )port + 1 ) ; #endif return( data ) ; }
/* This function will return the current system date & time in the passed pointer parameters. Note : The year is only 2 digits and the RTC is Real Time Clock and donot confuse it with the Y2K problem. The Day of week problem is still unsolved */ void GetLocalTime(SYSTEMTIME * lpSystemTime) { /* Checking whether we can read the time now or not according to some documentation the MSB in Status A will remain 1 (invalid time) only a millisecond*/ int TimeOut; OutPortByte( RTC_INDEX_REG, RTC_STATUS_A ); //check status - read access TimeOut = 1000; while ( InPortByte( RTC_VALUE_REG ) & 0x80 ) if ( TimeOut < 0 ) return; else TimeOut--; OutPortByte( RTC_INDEX_REG, RTC_DAY ); //get day value lpSystemTime->wDay = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_MONTH ); //get month value lpSystemTime->wMonth = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_YEAR ); //get year lpSystemTime->wYear = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_DAY_OF_WEEK ); //get day of week - **** problem lpSystemTime->wDayOfWeek = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_SECOND ); lpSystemTime->wSecond = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_MINUTE ); lpSystemTime->wMinute = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_HOUR ); lpSystemTime->wHour = InPortByte( RTC_VALUE_REG ); OutPortByte( RTC_INDEX_REG, RTC_STATUS_B ); OutPortByte( RTC_VALUE_REG, 2 ); return; }
/* Returns 1 on success and 0 on failue */ BYTE SetLocalTime(SYSTEMTIME * lpSystemTime) { /* Checking whether we can read the time now or not according to some documentation the MSB in Status A will remain 1 (invalid time) only a millisecond*/ int TimeOut; OutPortByte( RTC_INDEX_REG, RTC_STATUS_A ); //checking status -read access TimeOut = 1000; while ( InPortByte(RTC_VALUE_REG) & 0x80 ) if ( TimeOut< 0 ) return 0; else TimeOut--; OutPortByte( RTC_INDEX_REG, RTC_DAY ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wDay ); OutPortByte( RTC_INDEX_REG, RTC_MONTH ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wMonth ); OutPortByte( RTC_INDEX_REG, RTC_YEAR ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wYear ); OutPortByte( RTC_INDEX_REG, RTC_SECOND ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wSecond ); OutPortByte( RTC_INDEX_REG, RTC_MINUTE ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wMinute ); OutPortByte( RTC_INDEX_REG, RTC_HOUR ); OutPortByte( RTC_VALUE_REG, lpSystemTime->wHour ); return 1; }
BOOLEAN IsDeviceDataReady(int DeviceController, DWORD WaitUpToms = 0, BOOLEAN CheckDataRequest = TRUE) { UINT32 Time1, Time2; Time1 = GetTickCount(); do { UINT16 PortID = IDE_Con_IOBases[DeviceController][0] + IDE_CB_STATUS; BYTE Status = InPortByte(PortID); if ((Status & 0x80) == 0) //Checking BSY bit, because DRDY bit is valid only when BSY is zero { if (Status & 0x40) //checking DRDY is set if (CheckDataRequest) // if DataRequest is also needed { if (Status & 0x8) // DRQ bit set { return TRUE; } } else { return TRUE; } } Time2 = GetTickCount(); } while ((Time2 - Time1) < WaitUpToms); return FALSE; }
/* --------------------------------------------------------------------- */ UCHAR XGINew_GetReg2( USHORT port ) { UCHAR data ; data = InPortByte( port ) ; return( data ) ; }
/* --------------------------------------------------------------------- */ UCHAR XGINew_GetReg1( USHORT port , USHORT index ) { UCHAR data ; OutPortByte( ( ULONG )port , index ) ; data = InPortByte( ( ULONG )port + 1 ) ; return( data ) ; }
/* This function performs a Software Reset on the devices attached. You may specifing only one or one portion of a hard disk but all harddisks and entire space is subjected to sofware reset and the status is posted in the Error Register. 1) Set the SRST bit to 1, wait for 400ns 2) Clear the SRST bit to 0 3) Wait for BSY bit cleared in the Status Register upto 31 seconds 4) Read the Error Register Input : DeviceController Number Output : ( Output == 0x1 ) Device 0 passed, Device 1 passed or not present ( Output == 0x0 || ( Output >=0x2 && Output <=0x7F ) ) Device 0 failed, Device 1 passed or not present ( Output == 0x81 ) Device 0 passed, Device 1 failed ( Output == 0x80 || ( Output >=0x82 && Output <=0xFF ) ) Device 0 failed, Device 1 failed */ BYTE HardDiskHandler::DoSoftwareReset(UINT16 DeviceController) { BYTE DeviceControl = 4; //Setting SRST bit in the control register ( 2nd bit (bit count 3) ) OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CON_DEVICE_CONTROL, DeviceControl); DeviceControl = 0; //Clearing the SRST bit in the control register ( 2nd bit) OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CON_DEVICE_CONTROL, DeviceControl); return InPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_ERROR); }
BOOLEAN IsDeviceControllerBusy(int DeviceController, BYTE WaitUpToms = 0) { UINT32 Time1, Time2; Time1 = GetTickCount(); do { UINT16 PortID = IDE_Con_IOBases[DeviceController][0] + IDE_CB_STATUS; BYTE Status = InPortByte(PortID); if ((Status & 0x80) == 0) //BSY bit return FALSE; Time2 = GetTickCount(); } while ((Time2 - Time1) <= WaitUpToms); return TRUE; }
bool HalpEnableA20(void) { int *test_1 = (int *)0x00000000, test_1_buf; int *test_2 = (int *)0x00100000, test_2_buf; UCHAR status, flag; /* read current falg */ do { status = InPortByte(0x64); } while (status & 0x02); OutPortByte(0x64, 0xd0); do { status = InPortByte(0x64); } while (!(status & 0x01)); flag = InPortByte(0x60); flag |= 0x02; /* enable a20 */ /* write modified flag */ do { status = InPortByte(0x64); } while (status & 0x02); OutPortByte(0x64, 0xd1); do { status = InPortByte(0x64); } while (status & 0x02); OutPortByte(0x60, flag); /* write new flag */ /* wait until the new flag has adapted */ do { status = InPortByte(0x64); } while (status & 0x02); /* test a20 line */ test_1_buf = *test_1; test_2_buf = *test_2; *test_1 = 0xff00ccaa; *test_2 = 0x22cc11dd; if (*test_1 == *test_2) { *test_1 = test_1_buf; return false; } *test_1 = test_1_buf; *test_2 = test_2_buf; return true; }
void HardDiskHandler::Initialize() { char strKey[3]; strKey[0] = 'H'; //HDD type ID strKey[1] = '0'; //First HDD strKey[2] = 0; //Null Character //SetIDT(32+14,_HDDInterruptHandler); //SetIDT(32+15,_HDDInterruptHandler); HDDs.Initialize(); for (BYTE DeviceController = 0; DeviceController < IDE_MAX_CONTROLLER; DeviceController++) { DoSoftwareReset(DeviceController); if (IsDeviceControllerBusy(DeviceController)) //if device controller is busy then skipping { DebugPrintf("\nController Busy"); continue; } OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_COMMAND, IDE_COM_EXECUTE_DEVICE_DIAGNOSTIC); if (IsDeviceControllerBusy(DeviceController, 6)) { DebugPrintf("\nController busy after EXE"); continue; } BYTE Result = InPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_ERROR); for (BYTE Device = 0; Device < 2; Device++) // loop for master and slave disks { UINT16 DeviceID_Data[512], j; if (Device == 0 && !(Result & 1)) continue; if (Device == 1 && (Result & 0x80)) continue; if (Device == 1) OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_DEVICE_HEAD, 0x10); //Setting 4th bit(count 5) to set device as 1 else OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_DEVICE_HEAD, 0x0); sleep(50); OutPortByte(IDE_Con_IOBases[DeviceController][0] + IDE_CB_COMMAND, IDE_COM_IDENTIFY_DEVICE); if (!IsDeviceDataReady(DeviceController, 600, TRUE)) { DebugPrintf("\nData not ready %d", DeviceController); continue; } /*Reading 512 bytes of information from the Device*/ for (j = 0; j < 256; j++) DeviceID_Data[j] = InPortWord(IDE_Con_IOBases[DeviceController][0] + IDE_CB_DATA); /* Creating new HDD node for the Collection HDDs */ //struct __HDDInfo * newHDD; __HDDInfo * newHDD=(__HDDInfo *)kmalloc(sizeof(__HDDInfo)); if (newHDD == NULL) { DebugPrintf("\nHDD Initialize :: Allocation failed"); return; } newHDD->IORegisterIdx = DeviceController; memcpy(newHDD->DeviceID, DeviceID_Data, 512); newHDD->DeviceNumber = Device; newHDD->LastError = 0; newHDD->BytesPerSector = 512; //-------------Modify Code newHDD->CHSCylinderCount = DeviceID_Data[1]; newHDD->CHSHeadCount = DeviceID_Data[3]; newHDD->CHSSectorCount = DeviceID_Data[6]; if (DeviceID_Data[10] == 0) strcpy(newHDD->SerialNumber, "N/A"); else for (j = 0; j < 20; j += 2) { newHDD->SerialNumber[j] = DeviceID_Data[10 + (j / 2)] >> 8; newHDD->SerialNumber[j + 1] = (DeviceID_Data[10 + (j / 2)] << 8) >> 8; } if (DeviceID_Data[23] == 0) strcpy(newHDD->FirmwareRevision, "N/A"); else for (j = 0; j < 8; j += 2) { newHDD->FirmwareRevision[j] = DeviceID_Data[23 + (j / 2)] >> 8; newHDD->FirmwareRevision[j + 1] = (DeviceID_Data[23 + (j / 2)] << 8) >> 8; } if (DeviceID_Data[27] == 0) strcpy(newHDD->ModelNumber, "N/A"); else for (j = 0; j < 20; j += 2) { newHDD->ModelNumber[j] = DeviceID_Data[27 + (j / 2)] >> 8; newHDD->ModelNumber[j + 1] = (DeviceID_Data[27 + (j / 2)] << 8) >> 8; } newHDD->LBASupported = DeviceID_Data[49] & 0x200; newHDD->DMASupported = DeviceID_Data[49] & 0x100; UINT32 LBASectors = DeviceID_Data[61]; LBASectors = LBASectors << 16; LBASectors |= DeviceID_Data[60]; newHDD->LBACount = LBASectors; HDDs.Add(newHDD, strKey); strKey[1]++; } } }