reactos操作系统实现(111)

IdeSendSmartCommand函数主要发送IDE的命令。具体实现代码如下:

#001  ULONG

#002  NTAPI

#003  IdeSendSmartCommand(

#004      IN PVOID HwDeviceExtension,

#005      IN PSCSI_REQUEST_BLOCK Srb

#006      )

#007 

#008  /*++

#009 

#010  Routine Description:

#011 

#012      This routine handles SMART enable, disable, read attributes and threshold commands.

#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];

 

SRB获取输入参数和输出参数。

#029      PSENDCMDOUTPARAMS    cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));

#030      SENDCMDINPARAMS      cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));

#031      PIDEREGS             regs = &cmdInParameters.irDriveRegs;

#032      ULONG                i;

#033      UCHAR                statusByte,targetId;

#034 

#035 

 

检查是否合法的操作。

#036      if (cmdInParameters.irDriveRegs.bCommandReg == SMART_CMD) {

#037 

#038          targetId = cmdInParameters.bDriveNumber;

#039 

#040          //TODO optimize this check

#041 

#042          if ((!(deviceExtension->DeviceFlags[targetId] & DFLAGS_DEVICE_PRESENT)) ||

#043               (deviceExtension->DeviceFlags[targetId] & DFLAGS_ATAPI_DEVICE)) {

#044 

#045              return SRB_STATUS_SELECTION_TIMEOUT;

#046          }

#047 

 

获取输出的命令。

#048          deviceExtension->SmartCommand = cmdInParameters.irDriveRegs.bFeaturesReg;

#049 

#050          //

#051          // Determine which of the commands to carry out.

#052          //

#053 

 

检查命令是否读取的操作。

#054          if ((cmdInParameters.irDriveRegs.bFeaturesReg == READ_ATTRIBUTES) ||

#055              (cmdInParameters.irDriveRegs.bFeaturesReg == READ_THRESHOLDS)) {

#056 

 

等待IDE设备空闲。

#057              WaitOnBusy(baseIoAddress2,statusByte);

#058 

#059              if (statusByte & IDE_STATUS_BUSY) {

#060                  DebugPrint((1,

#061                              "IdeSendSmartCommand: Returning BUSY status/n"));

#062                  return SRB_STATUS_BUSY;

#063              }

#064 

#065              //

#066              // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).

#067              //

#068 

 

清空输出缓冲区。

#069              for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + READ_ATTRIBUTE_BUFFER_SIZE - 1); i++) {

#070                  ((PUCHAR)cmdOutParameters)[i] = 0;

#071              }

#072 

#073              //

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

#075              //

#076 

 

设置输出缓冲区作为接收IDE设备的数据保存区。

#077              deviceExtension->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;

#078              deviceExtension->WordsLeft = READ_ATTRIBUTE_BUFFER_SIZE / 2;

#079  

#080              //

#081              // Indicate expecting an interrupt.

#082              //

#083 

 

这里设置希望使用中断的方式返回。

#084              deviceExtension->ExpectingInterrupt = TRUE;

#085 

 

SRB的命令发送给IDE设备。

#086              ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,(UCHAR)(((targetId & 0x1) << 4) | 0xA0));

#087              ScsiPortWritePortUchar((PUCHAR)baseIoAddress1 + 1,regs->bFeaturesReg);

#088              ScsiPortWritePortUchar(&baseIoAddress1->BlockCount,regs->bSectorCountReg);

#089              ScsiPortWritePortUchar(&baseIoAddress1->BlockNumber,regs->bSectorNumberReg);

#090              ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow,regs->bCylLowReg);

#091              ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,regs->bCylHighReg);

#092              ScsiPortWritePortUchar(&baseIoAddress1->Command,regs->bCommandReg);

#093 

#094              //

#095              // Wait for interrupt.

#096              //

#097 

 

进入等待中断读取数据返回。

#098              return SRB_STATUS_PENDING;

#099 

#100          } else if ((cmdInParameters.irDriveRegs.bFeaturesReg == ENABLE_SMART) ||

#101                     (cmdInParameters.irDriveRegs.bFeaturesReg == DISABLE_SMART) ||

#102                     (cmdInParameters.irDriveRegs.bFeaturesReg == RETURN_SMART_STATUS) ||

#103                     (cmdInParameters.irDriveRegs.bFeaturesReg == ENABLE_DISABLE_AUTOSAVE) ||

#104                     (cmdInParameters.irDriveRegs.bFeaturesReg == EXECUTE_OFFLINE_DIAGS) ||

#105                     (cmdInParameters.irDriveRegs.bFeaturesReg == SAVE_ATTRIBUTE_VALUES)) {

#106 

 

这是设置一些属性,没有数据返回。

#107              WaitOnBusy(baseIoAddress2,statusByte);

#108 

#109              if (statusByte & IDE_STATUS_BUSY) {

#110                  DebugPrint((1,

#111                              "IdeSendSmartCommand: Returning BUSY status/n"));

#112                  return SRB_STATUS_BUSY;

#113              }

#114 

#115              //

#116              // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).

#117              //

#118 

#119              for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) - 1); i++) {

#120                  ((PUCHAR)cmdOutParameters)[i] = 0;

#121              }

#122 

#123              //

#124              // Set data buffer pointer and indicate no data transfer.

#125              //

#126 

#127              deviceExtension->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;

#128              deviceExtension->WordsLeft = 0;

#129 

#130              //

#131              // Indicate expecting an interrupt.

#132              //

#133 

#134              deviceExtension->ExpectingInterrupt = TRUE;

#135 

#136              ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,(UCHAR)(((targetId & 0x1) << 4) | 0xA0));

#137              ScsiPortWritePortUchar((PUCHAR)baseIoAddress1 + 1,regs->bFeaturesReg);

#138              ScsiPortWritePortUchar(&baseIoAddress1->BlockCount,regs->bSectorCountReg);

#139              ScsiPortWritePortUchar(&baseIoAddress1->BlockNumber,regs->bSectorNumberReg);

#140              ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow,regs->bCylLowReg);

#141              ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,regs->bCylHighReg);

#142              ScsiPortWritePortUchar(&baseIoAddress1->Command,regs->bCommandReg);

#143 

#144              //

#145              // Wait for interrupt.

#146              //

#147 

#148              return SRB_STATUS_PENDING;

#149          }

#150      }

#151 

 

如果到这里运行,就是非法命令,不能处理。

#152      return SRB_STATUS_INVALID_REQUEST;

#153 

#154  } // end IdeSendSmartCommand()

posted @ 2009-10-21 20:59  ajuanabc  阅读(148)  评论(0编辑  收藏  举报