reactos操作系统实现(112)

IdeReadWrite函数主要实现了IDE设备的读和写命令发送。具体实现函数如下:

#001  ULONG

#002  NTAPI

#003  IdeReadWrite(

#004      IN PVOID HwDeviceExtension,

#005      IN PSCSI_REQUEST_BLOCK Srb

#006      )

#007 

#008  /*++

#009 

#010  Routine Description:

#011 

#012      This routine handles IDE read and writes.

#013 

#014  Arguments:

#015 

#016      HwDeviceExtension - HBA miniport driver's adapter data storage

#017      Srb - IO request packet

#018 

#019  Return Value:

#020 

#021      SRB status

#022 

#023  --*/

#024 

#025  {

 

获取驱动程序扩展对象和基地址寄存器。

#026      PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;

#027      PIDE_REGISTERS_1     baseIoAddress1  = deviceExtension->BaseIoAddress1[Srb->TargetId >> 1];

#028      PIDE_REGISTERS_2     baseIoAddress2  = deviceExtension->BaseIoAddress2[Srb->TargetId >> 1];

#029      ULONG                startingSector,i;

#030      ULONG                wordCount;

#031      UCHAR                statusByte,statusByte2;

#032      UCHAR                cylinderHigh,cylinderLow,drvSelect,sectorNumber;

#033 

#034      //

#035      // Select device 0 or 1.

#036      //

#037 

 

选择IDE设备0,还是设备1.

#038      ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#039                              (UCHAR)(((Srb->TargetId & 0x1) << 4) | 0xA0));

#040 

 

等待选择设备命令完成。

#041      WaitOnBusy(baseIoAddress2,statusByte2);

#042 

 

如果命令没有执行成功就返回。

#043      if (statusByte2 & IDE_STATUS_BUSY) {

#044          DebugPrint((1,

#045                      "IdeReadWrite: Returning BUSY status/n"));

#046          return SRB_STATUS_BUSY;

#047      }

#048 

#049      //

#050      // Set data buffer pointer and words left.

#051      //

#052 

 

设置输出或读取缓冲区和传送的字节个数。

#053      deviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer;

#054      deviceExtension->WordsLeft = Srb->DataTransferLength / 2;

#055 

#056      //

#057      // Indicate expecting an interrupt.

#058      //

#059 

 

设置期望使用中断响应。

#060      deviceExtension->ExpectingInterrupt = TRUE;

#061 

#062      //

#063      // Set up sector count register. Round up to next block.

#064      //

#065 

 

设置要传送的扇区寄器。

#066      ScsiPortWritePortUchar(&baseIoAddress1->BlockCount,

#067                             (UCHAR)((Srb->DataTransferLength + 0x1FF) / 0x200));

#068 

#069      //

#070      // Get starting sector number from CDB.

#071      //

#072 

 

SRB请求的CDB块计算开始的扇区。

#073      startingSector = ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte3 |

#074                       ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte2 << 8 |

#075                       ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 |

#076                       ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24;

#077 

#078      DebugPrint((2,

#079                 "IdeReadWrite: Starting sector is %x, Number of bytes %x/n",

#080                 startingSector,

#081                 Srb->DataTransferLength));

#082 

#083      //

#084      // Set up sector number register.

#085      //

#086 

 

计算扇区开始位置,并写入到寄存器。

#087      sectorNumber =  (UCHAR)((startingSector % deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) + 1);

#088      ScsiPortWritePortUchar(&baseIoAddress1->BlockNumber,sectorNumber);

#089 

#090      //

#091      // Set up cylinder low register.

#092      //

#093 

 

下面开始计算柱面位置。

#094      cylinderLow =  (UCHAR)(startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack *

#095                             deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads));

#096      ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow,cylinderLow);

#097 

#098      //

#099      // Set up cylinder high register.

#100      //

#101 

#102      cylinderHigh = (UCHAR)((startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack *

#103                             deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)) >> 8);

#104      ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,cylinderHigh);

#105 

#106      //

#107      // Set up head and drive select register.

#108      //

#109 

 

计算磁头位置。

#110      drvSelect = (UCHAR)(((startingSector / deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) %

#111                        deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) |((Srb->TargetId & 0x1) << 4) | 0xA0);

#112      ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,drvSelect);

#113 

#114      DebugPrint((2,

#115                 "IdeReadWrite: Cylinder %x Head %x Sector %x/n",

#116                 startingSector /

#117                 (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack *

#118                 deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads),

#119                 (startingSector /

#120                 deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) %

#121                 deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads,

#122                 startingSector %

#123                 deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack + 1));

#124 

#125      //

#126      // Check if write request.

#127      //

#128 

 

开始发送读或写命令给IDE设备。

#129      if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {

#130 

#131          //

#132          // Send read command.

#133          //

#134 

 

这里是读取扇区数据,所以发送读取命令给IDE设备。

#135          if (deviceExtension->MaximumBlockXfer[Srb->TargetId]) {

#136              ScsiPortWritePortUchar(&baseIoAddress1->Command,

#137                                     IDE_COMMAND_READ_MULTIPLE);

#138 

#139          } else {

#140              ScsiPortWritePortUchar(&baseIoAddress1->Command,

#141                                     IDE_COMMAND_READ);

#142          }

#143      } else {

#144 

#145 

#146          //

#147          // Send write command.

#148          //

#149 

 

这里是写入数据到IDE设备,所以发送写入命令。

#150          if (deviceExtension->MaximumBlockXfer[Srb->TargetId]) {

#151              wordCount = 256 * deviceExtension->MaximumBlockXfer[Srb->TargetId];

#152 

#153              if (deviceExtension->WordsLeft < wordCount) {

#154 

#155                 //

#156                 // Transfer only words requested.

#157                 //

#158 

#159                 wordCount = deviceExtension->WordsLeft;

#160 

#161              }

#162              ScsiPortWritePortUchar(&baseIoAddress1->Command,

#163                                     IDE_COMMAND_WRITE_MULTIPLE);

#164 

#165          } else {

#166              wordCount = 256;

#167              ScsiPortWritePortUchar(&baseIoAddress1->Command,

#168                                     IDE_COMMAND_WRITE);

#169          }

#170 

#171          //

#172          // Wait for BSY and DRQ.

#173          //

#174 

 

    等待读取或写入命令完成。

#175          WaitOnBaseBusy(baseIoAddress1,statusByte);

#176 

 

如果设备还是忙状态,说明读取或写命令有问题。

#177          if (statusByte & IDE_STATUS_BUSY) {

#178 

#179              DebugPrint((1,

#180                          "IdeReadWrite 2: Returning BUSY status %x/n",

#181                          statusByte));

#182              return SRB_STATUS_BUSY;

#183          }

#184 

#185          for (i = 0; i < 1000; i++) {

#186              GetBaseStatus(baseIoAddress1, statusByte);

#187              if (statusByte & IDE_STATUS_DRQ) {

#188                  break;

#189              }

#190              ScsiPortStallExecution(200);

#191 

#192          }

#193 

如果不是状态IDE_STATUS_DRQ,说明处理命令出错了。

#194          if (!(statusByte & IDE_STATUS_DRQ)) {

#195 

#196              DebugPrint((1,

#197                         "IdeReadWrite: DRQ never asserted (%x) original status (%x)/n",

#198                         statusByte,

#199                         statusByte2));

#200 

#201              deviceExtension->WordsLeft = 0;

#202 

#203              //

#204              // Clear interrupt expecting flag.

#205              //

#206 

#207              deviceExtension->ExpectingInterrupt = FALSE;

#208 

#209              //

#210              // Clear current SRB.

#211              //

#212 

#213              deviceExtension->CurrentSrb = NULL;

#214 

#215              return SRB_STATUS_TIMEOUT;

#216          }

#217 

#218          //

#219          // Write next 256 words.

#220          //

#221 

 

512个字节到IDE设备。

#222          WriteBuffer(baseIoAddress1,

#223                      deviceExtension->DataBuffer,

#224                      wordCount);

#225 

#226          //

#227          // Adjust buffer address and words left count.

#228          //

#229 

 

计算已经传送的字节数。

#230          deviceExtension->WordsLeft -= wordCount;

#231          deviceExtension->DataBuffer += wordCount;

#232 

#233      }

#234 

#235      //

#236      // Wait for interrupt.

#237      //

#238 

#239      return SRB_STATUS_PENDING;

#240 

#241  } // end IdeReadWrite()

你可能感兴趣的:(IO,command,ide,扩展,UP,returning)