hardware.c
来自「一个类似windows」· C语言 代码 · 共 1,084 行 · 第 1/3 页
C
1,084 行
Buffer[1] = DriveInfo->UnitNumber; /* hard-wired to head 0 for now */
for(i = 0; i < 2; i++)
if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSenseDriveStatus: failed to write FIFO\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
BOOLEAN Read,
UCHAR Unit,
UCHAR Cylinder,
UCHAR Head,
UCHAR Sector,
UCHAR BytesPerSector,
UCHAR EndOfTrack,
UCHAR Gap3Length,
UCHAR DataLength)
/*
* FUNCTION: Read or write data to the drive
* ARGUMENTS:
* ControllerInfo: controller to target the read/write request to
* Read: TRUE if the device should be read; FALSE if written
* Unit: Drive number to target
* Cylinder: cylinder to start the read on
* Head: head to start the read on
* Sector: sector to start the read on (1-based!)
* BytesPerSector: sector size constant (hardware.h)
* EndOfTrack: Marks the last sector number to read/write on the track
* Gap3Length: Gap length for the operation
* DataLength: Bytes to read, *unless* BytesPerSector is specified
* RETURNS:
* STATUS_SUCCESS if the operation was successfully queued to the controller
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - Generates an interrupt
*/
{
UCHAR Buffer[9];
int i;
PAGED_CODE();
/* Shouldn't be using DataLength in this driver */
ASSERT(DataLength == 0xff);
/* Build the command to send */
if(Read)
Buffer[0] = COMMAND_READ_DATA;
else
Buffer[0] = COMMAND_WRITE_DATA;
Buffer[0] |= READ_DATA_MFM | READ_DATA_MT;
Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
Buffer[2] = Cylinder;
Buffer[3] = Head;
Buffer[4] = Sector;
Buffer[5] = BytesPerSector;
Buffer[6] = EndOfTrack;
Buffer[7] = Gap3Length;
Buffer[8] = DataLength;
/* Send the command */
for(i = 0; i < 9; i++)
{
DPRINT("floppy: HwReadWriteData: Sending a command byte to the FIFO: 0x%x\n", Buffer[i]);
if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("HwReadWriteData: Unable to write to the FIFO\n");
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Get the result of a recalibrate command
* ARGUMENTS:
* ControllerInfo: controller to query
* RETURNS:
* STATUS_SUCCESS if the recalibratewas 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[2];
int i;
PAGED_CODE();
if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
{
DPRINT("floppy: HwRecalibrateResult: Unable to write the controller\n");
return STATUS_UNSUCCESSFUL;
}
for(i = 0; i < 2; i++)
if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwRecalibrateResult: unable to read FIFO\n");
return STATUS_UNSUCCESSFUL;
}
/* Validate that it did what we told it to */
DPRINT("floppy: HwRecalibrateResult results: ST0: 0x%x PCN: 0x%x\n", Buffer[0], Buffer[1]);
/*
* Buffer[0] = ST0
* Buffer[1] = PCN
*/
/* Is the PCN 0? */
if(Buffer[1] != 0)
{
DPRINT("floppy: HwRecalibrateResult: PCN not 0\n");
return STATUS_UNSUCCESSFUL;
}
/* test seek complete */
if((Buffer[0] & SR0_SEEK_COMPLETE) != SR0_SEEK_COMPLETE)
{
DPRINT("floppy: HwRecalibrateResult: Failed to complete the seek\n");
return STATUS_UNSUCCESSFUL;
}
/* Is the equipment check flag set? Could be no disk in drive... */
if((Buffer[0] & SR0_EQUIPMENT_CHECK) == SR0_EQUIPMENT_CHECK)
DPRINT("floppy: HwRecalibrateResult: Seeked to track 0 successfully, but EC is set; returning STATUS_SUCCESS anyway\n");
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Get the result of a read or write from the controller
* ARGUMENTS:
* ControllerInfo: controller to query
* RETURNS:
* STATUS_SUCCESS if the read/write 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];
int i;
PAGED_CODE();
for(i = 0; i < 7; i++)
if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwReadWriteResult: unable to read fifo\n");
return STATUS_UNSUCCESSFUL;
}
/* Validate that it did what we told it to */
DPRINT("floppy: HwReadWriteResult 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)
return STATUS_UNSUCCESSFUL;
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Start a recalibration of a drive
* ARGUMENTS:
* DriveInfo: Drive to recalibrate
* RETURNS:
* STATUS_SUCCESS if the command was successfully queued to the controller
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - Generates an interrupt
*/
{
PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
UCHAR Unit = DriveInfo->UnitNumber;
UCHAR Buffer[2];
int i;
DPRINT("floppy: HwRecalibrate called\n");
PAGED_CODE();
Buffer[0] = COMMAND_RECALIBRATE;
Buffer[1] = Unit;
for(i = 0; i < 2; i++)
if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwRecalibrate: unable to write FIFO\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Send a sense interrupt status command to a controller
* ARGUMENTS:
* ControllerInfo: controller to queue the command to
* RETURNS:
* STATUS_SUCCESS if the command is queued successfully
* STATUS_UNSUCCESSFUL if not
*/
{
UCHAR Buffer[2];
int i;
PAGED_CODE();
if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSenseInterruptStatus: failed to write controller\n");
return STATUS_UNSUCCESSFUL;
}
for(i = 0; i < 2; i++)
{
if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwSenseInterruptStatus: failed to read controller\n");
return STATUS_UNSUCCESSFUL;
}
}
DPRINT("floppy: HwSenseInterruptStatus returned 0x%x 0x%x\n", Buffer[0], Buffer[1]);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head)
/*
* FUNCTION: Issue a read id command to the drive
* ARGUMENTS:
* DriveInfo: Drive to read id from
* Head: Head to read the ID from
* RETURNS:
* STATUS_SUCCESS if the command is queued
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - Generates an interrupt
*/
{
UCHAR Buffer[2];
int i;
DPRINT("floppy: HwReadId called\n");
PAGED_CODE();
Buffer[0] = COMMAND_READ_ID | READ_ID_MFM;
Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | DriveInfo->UnitNumber;
for(i = 0; i < 2; i++)
if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwReadId: unable to send bytes to fifo\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
UCHAR Unit,
UCHAR Head,
UCHAR BytesPerSector,
UCHAR SectorsPerTrack,
UCHAR Gap3Length,
UCHAR FillerPattern)
/*
* FUNCTION: Format a track
* ARGUMENTS:
* ControllerInfo: controller to target with the request
* Unit: drive to format on
* Head: head to format on
* BytesPerSector: constant from hardware.h to select density
* SectorsPerTrack: sectors per track
* Gap3Length: gap length to use during format
* FillerPattern: pattern to write into the data portion of sectors
* RETURNS:
* STATUS_SUCCESS if the command is successfully queued
* STATUS_UNSUCCESSFUL otherwise
*/
{
UCHAR Buffer[6];
int i;
DPRINT("floppy: HwFormatTrack called\n");
PAGED_CODE();
Buffer[0] = COMMAND_FORMAT_TRACK;
Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
Buffer[2] = BytesPerSector;
Buffer[3] = SectorsPerTrack;
Buffer[4] = Gap3Length;
Buffer[5] = FillerPattern;
for(i = 0; i < 6; i++)
if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
{
DPRINT("floppy: HwFormatTrack: unable to send bytes to floppy\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS NTAPI HwSeek(PDRIVE_INFO DriveInfo,
UCHAR Cylinder)
/*
* FUNCTION: Seek the heads to a particular cylinder
* ARGUMENTS:
* DriveInfo: Drive to seek
* Cylinder: cylinder to move to
* RETURNS:
* STATUS_SUCCESS if the command is successfully sent
* STATUS_UNSUCCESSFUL otherwise
* NOTES:
* - Generates an interrupt
*/
{
LARGE_INTEGER Delay;
UCHAR Buffer[3];
int i;
DPRINT("floppy: HwSeek called for cyl 0x%x\n", Cylinder);
PAGED_CODE();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?