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 + -
显示快捷键?