hardware.c
来自「一个类似windows」· C语言 代码 · 共 1,084 行 · 第 1/3 页
C
1,084 行
Buffer[0] = COMMAND_SEEK;
Buffer[1] = DriveInfo->UnitNumber;
Buffer[2] = Cylinder;
for(i = 0; i < 3; i++)
if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSeek: failed to write fifo\n");
return STATUS_UNSUCCESSFUL;
}
/* Wait for the head to settle */
Delay.QuadPart = 10 * 1000;
Delay.QuadPart *= -1;
Delay.QuadPart *= DriveInfo->FloppyDeviceData.HeadSettleTime;
KeDelayExecutionThread(KernelMode, FALSE, &Delay);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwConfigure(PCONTROLLER_INFO ControllerInfo,
BOOLEAN EIS,
BOOLEAN EFIFO,
BOOLEAN POLL,
UCHAR FIFOTHR,
UCHAR PRETRK)
/*
* FUNCTION: Sends configuration to the drive
* ARGUMENTS:
* ControllerInfo: controller to target with the request
* EIS: Enable implied seek
* EFIFO: Enable advanced fifo
* POLL: Enable polling
* FIFOTHR: fifo threshold
* PRETRK: precomp (see intel datasheet)
* RETURNS:
* STATUS_SUCCESS if the command is successfully sent
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - No interrupt
*/
{
UCHAR Buffer[4];
int i;
DPRINT("floppy: HwConfigure called\n");
PAGED_CODE();
Buffer[0] = COMMAND_CONFIGURE;
Buffer[1] = 0;
Buffer[2] = (EIS * CONFIGURE_EIS) + (EFIFO * CONFIGURE_EFIFO) + (POLL * CONFIGURE_POLL) + (FIFOTHR);
Buffer[3] = PRETRK;
for(i = 0; i < 4; i++)
if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwConfigure: failed to write the fifo\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Gets the version of the controller
* ARGUMENTS:
* ControllerInfo: controller to target with the request
* ConfigValue: Configuration value to send to the drive (see header)
* RETURNS:
* Version number returned by the command, or
* 0 on failure
* NOTE:
* - This command doesn't interrupt, so we go right to reading after
* we issue the command
*/
{
UCHAR Buffer;
PAGED_CODE();
if(Send_Byte(ControllerInfo, COMMAND_VERSION) != STATUS_SUCCESS)
{
DPRINT("floppy: HwGetVersion: unable to write fifo\n");
return STATUS_UNSUCCESSFUL;
}
if(Get_Byte(ControllerInfo, &Buffer) != STATUS_SUCCESS)
{
DPRINT("floppy: HwGetVersion: unable to write fifo\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT("floppy: HwGetVersion returning version 0x%x\n", Buffer);
return Buffer;
}
NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo,
PBOOLEAN DiskChanged)
/*
* FUNCTION: Detect whether the hardware has sensed a disk change
* ARGUMENTS:
* DriveInfo: pointer to the drive that we are to check
* DiskChanged: boolean that is set with whether or not the controller thinks there has been a disk change
* RETURNS:
* STATUS_SUCCESS if the drive is successfully queried
* NOTES:
* - Does not interrupt.
* - Guessing a bit at the Model30 stuff
*/
{
UCHAR Buffer;
PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO) DriveInfo->ControllerInfo;
Buffer = READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER);
DPRINT("floppy: HwDiskChanged: read 0x%x from DIR\n", Buffer);
if(ControllerInfo->Model30)
{
if(!(Buffer & DIR_DISKETTE_CHANGE))
{
DPRINT("floppy: HdDiskChanged - Model30 - returning TRUE\n");
*DiskChanged = TRUE;
}
else
{
DPRINT("floppy: HdDiskChanged - Model30 - returning FALSE\n");
*DiskChanged = FALSE;
}
}
else
{
if(Buffer & DIR_DISKETTE_CHANGE)
{
DPRINT("floppy: HdDiskChanged - PS2 - returning TRUE\n");
*DiskChanged = TRUE;
}
else
{
DPRINT("floppy: HdDiskChanged - PS2 - returning FALSE\n");
*DiskChanged = FALSE;
}
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo,
PUCHAR Status)
/*
* FUNCTION: Get the result of a sense drive status command
* ARGUMENTS:
* ControllerInfo: controller to query
* Status: Status from the drive sense command
* RETURNS:
* STATUS_SUCCESS if we can successfully read the status
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - Called post-interrupt; does not interrupt
*/
{
PAGED_CODE();
if(Get_Byte(ControllerInfo, Status) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSenseDriveStatus: unable to read fifo\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT("floppy: HwSenseDriveStatusResult: ST3: 0x%x\n", *Status);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
PUCHAR CurCylinder,
PUCHAR CurHead)
/*
* FUNCTION: Get the result of a read id command
* ARGUMENTS:
* ControllerInfo: controller to query
* CurCylinder: Returns the cylinder that we're at
* CurHead: Returns the head that we're at
* RETURNS:
* STATUS_SUCCESS if the read id was a success
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - This function tests the error conditions itself, and boils the
* whole thing down to a single SUCCESS or FAILURE result
* - Called post-interrupt; does not interrupt
* TODO
* - perhaps handle more status
*/
{
UCHAR Buffer[7] = {0,0,0,0,0,0,0};
int i;
PAGED_CODE();
for(i = 0; i < 7; i++)
if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: ReadIdResult(): can't read from the controller\n");
return STATUS_UNSUCCESSFUL;
}
/* Validate that it did what we told it to */
DPRINT("floppy: ReadId results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3],
Buffer[4], Buffer[5], Buffer[6]);
/* Last command successful? */
if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS)
{
DPRINT("floppy: ReadId didn't return last command success\n");
return STATUS_UNSUCCESSFUL;
}
/* ID mark found? */
if(Buffer[1] & SR1_CANNOT_FIND_ID_ADDRESS)
{
DPRINT("floppy: ReadId didn't find an address mark\n");
return STATUS_UNSUCCESSFUL;
}
if(CurCylinder)
*CurCylinder = Buffer[3];
if(CurHead)
*CurHead = Buffer[4];
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo,
UCHAR HeadLoadTime,
UCHAR HeadUnloadTime,
UCHAR StepRateTime,
BOOLEAN NonDma)
/*
* FUNCTION: Set up timing and DMA mode for the controller
* ARGUMENTS:
* ControllerInfo: Controller to set up
* HeadLoadTime: Head load time (see data sheet for details)
* HeadUnloadTime: Head unload time
* StepRateTime: Step rate time
* NonDma: TRUE to disable DMA mode
* RETURNS:
* STATUS_SUCCESS if the contrller is successfully programmed
* STATUS_UNSUCCESSFUL if not
* NOTES:
* - Does not interrupt
*
* TODO: Figure out timings
*/
{
UCHAR Buffer[3];
int i;
Buffer[0] = COMMAND_SPECIFY;
/*
Buffer[1] = (StepRateTime << 4) + HeadUnloadTime;
Buffer[2] = (HeadLoadTime << 1) + (NonDma ? 1 : 0);
*/
Buffer[1] = 0xdf;
Buffer[2] = 0x2;
//DPRINT("HwSpecify: sending 0x%x 0x%x 0x%x to FIFO\n", Buffer[0], Buffer[1], Buffer[2]);
DPRINT("FLOPPY: HWSPECIFY: FIXME - sending 0x3 0xd1 0x2 to FIFO\n");
for(i = 0; i < 3; i++)
if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSpecify: unable to write to controller\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwReset(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Reset the controller
* ARGUMENTS:
* ControllerInfo: controller to reset
* RETURNS:
* STATUS_SUCCESS in all cases
* NOTES:
* - Generates an interrupt that must be serviced four times (one per drive)
*/
{
DPRINT("floppy: HwReset called\n");
/* Write the reset bit in the DRSR */
WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_SW_RESET);
/* Check for the reset bit in the DOR and set it if necessary (see Intel doc) */
if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
{
HwDumpRegisters(ControllerInfo);
DPRINT("floppy: HwReset: Setting Enable bit\n");
WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, DOR_DMA_IO_INTERFACE_ENABLE|DOR_RESET);
HwDumpRegisters(ControllerInfo);
if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
{
DPRINT("floppy: HwReset: failed to set the DOR enable bit!\n");
HwDumpRegisters(ControllerInfo);
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwPowerOff(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Power down a controller
* ARGUMENTS:
* ControllerInfo: Controller to power down
* RETURNS:
* STATUS_SUCCESS
* NOTES:
* - Wake up with a hardware reset
*/
{
DPRINT("floppy: HwPowerOff called on controller 0x%x\n", ControllerInfo);
WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_POWER_DOWN);
return STATUS_SUCCESS;
}
VOID NTAPI HwDumpRegisters(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Dump all readable registers from the floppy controller
* ARGUMENTS:
* ControllerInfo: Controller to dump registers from
*/
{
UNREFERENCED_PARAMETER(ControllerInfo);
DPRINT("floppy: STATUS: ");
DPRINT("STATUS_REGISTER_A = 0x%x ", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_A));
DPRINT("STATUS_REGISTER_B = 0x%x ", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_B));
DPRINT("DIGITAL_OUTPUT_REGISTER = 0x%x ", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER));
DPRINT("MAIN_STATUS_REGISTER =0x%x ", READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER));
DPRINT("DIGITAL_INPUT_REGISTER = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?