reactos操作系统实现(110)

news/2024/11/29 2:46:38/

AtapiStartIo函数主要处理同步的IO请求包。具代的实现代码如下:

#001  BOOLEAN

#002  NTAPI

#003  AtapiStartIo(

#004      IN PVOID HwDeviceExtension,

#005      IN PSCSI_REQUEST_BLOCK Srb

#006      )

#007 

#008  /*++

#009 

#010  Routine Description:

#011 

#012      This routine is called from the SCSI port driver synchronized

#013      with the kernel to start an IO request.

#014 

#015  Arguments:

#016 

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

#018      Srb - IO request packet

#019 

#020  Return Value:

#021 

#022      TRUE

#023 

#024  --*/

#025 

#026  {

#027      PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;

#028      ULONG status;

#029 

#030      //

#031      // Determine which function.

#032      //

#033 

 

检查SRB是做什么的功能。

#034      switch (Srb->Function) {

#035 

 

执行SCSI命令。

#036      case SRB_FUNCTION_EXECUTE_SCSI:

#037 

#038          //

#039          // Sanity check. Only one request can be outstanding on a

#040          // controller.

#041          //

#042 

 

检查当前SRB是否已经存在,如果存在就是出错返回。

#043          if (deviceExtension->CurrentSrb) {

#044 

#045              DebugPrint((1,

#046                         "AtapiStartIo: Already have a request!/n"));

#047              Srb->SrbStatus = SRB_STATUS_BUSY;

 

知道这个请求完成返回。

#048              ScsiPortNotification(RequestComplete,

#049                                   deviceExtension,

#050                                   Srb);

#051              return FALSE;

#052          }

#053 

#054          //

#055          // Indicate that a request is active on the controller.

#056          //

#057 

 

保存将要发送的SRB

#058          deviceExtension->CurrentSrb = Srb;

#059 

#060          //

#061          // Send command to device.

#062          //

#063 

 

把命令发送到设备。

#064          if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE) {

#065 

 

发送到ATAPI设备。

#066             status = AtapiSendCommand(HwDeviceExtension,

#067                                       Srb);

#068 

#069          } else if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) {

#070 

 

发送到IDE设备,但不是ATAPI设备。

#071             status = IdeSendCommand(HwDeviceExtension,

#072                                     Srb);

#073          } else {

#074 

 

否则没有设备可以发送。

#075              status = SRB_STATUS_SELECTION_TIMEOUT;

#076          }

#077 

#078          break;

#079 

 

放弃当前SRB输出。

#080      case SRB_FUNCTION_ABORT_COMMAND:

#081 

#082          //

#083          // Verify that SRB to abort is still outstanding.

#084          //

#085 

#086          if (!deviceExtension->CurrentSrb) {

#087 

#088              DebugPrint((1, "AtapiStartIo: SRB to abort already completed/n"));

#089 

#090              //

#091              // Complete abort SRB.

#092              //

#093 

#094              status = SRB_STATUS_ABORT_FAILED;

#095 

#096              break;

#097          }

#098 

#099          //

#100          // Abort function indicates that a request timed out.

#101          // Call reset routine. Card will only be reset if

#102          // status indicates something is wrong.

#103          // Fall through to reset code.

#104          //

#105 

 

下面对IDE控制器进行复位操作。

#106      case SRB_FUNCTION_RESET_BUS:

#107 

#108          //

#109          // Reset Atapi and SCSI bus.

#110          //

#111 

#112          DebugPrint((1, "AtapiStartIo: Reset bus request received/n"));

#113 

#114          if (!AtapiResetController(deviceExtension,

#115                               Srb->PathId)) {

#116 

#117                DebugPrint((1,"AtapiStartIo: Reset bus failed/n"));

#118 

#119              //

#120              // Log reset failure.

#121              //

#122 

#123              ScsiPortLogError(

#124                  HwDeviceExtension,

#125                  NULL,

#126                  0,

#127                  0,

#128                  0,

#129                  SP_INTERNAL_ADAPTER_ERROR,

#130                  5 << 8

#131                  );

#132 

#133                status = SRB_STATUS_ERROR;

#134 

#135          } else {

#136 

#137                status = SRB_STATUS_SUCCESS;

#138          }

#139 

#140          break;

#141 

 

 

#142      case SRB_FUNCTION_IO_CONTROL:

#143 

 

如果当前SRB还没有处理,就返回。

#144          if (deviceExtension->CurrentSrb) {

#145 

#146              DebugPrint((1,

#147                         "AtapiStartIo: Already have a request!/n"));

#148              Srb->SrbStatus = SRB_STATUS_BUSY;

#149              ScsiPortNotification(RequestComplete,

#150                                   deviceExtension,

#151                                   Srb);

#152              return FALSE;

#153          }

#154 

#155          //

#156          // Indicate that a request is active on the controller.

#157          //

#158 

 

保存SRB为当前SRB

#159          deviceExtension->CurrentSrb = Srb;

#160 

 

如果SCSIDISK的控制器,就不能处理,这是非法的请求。

#161          if (AtapiStringCmp( (PCHAR)((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,"SCSIDISK",strlen("SCSIDISK"))) {

#162 

#163              DebugPrint((1,

#164                          "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s/n",

#165                          ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,

#166                          "SCSIDISK"));

#167 

#168              status = SRB_STATUS_INVALID_REQUEST;

#169              break;

#170          }

#171 

 

根据IO的控制码来决定做什么样的事情。

#172          switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {

#173 

#174              case IOCTL_SCSI_MINIPORT_SMART_VERSION: {

#175 

 

设置SCSI的驱动程序的版本。

#176                  PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));

#177                  UCHAR deviceNumber;

#178 

#179                  //

#180                  // Version and revision per SMART 1.03

#181                  //

#182 

#183                  versionParameters->bVersion = 1;

#184                  versionParameters->bRevision = 1;

#185                  versionParameters->bReserved = 0;

#186 

#187                  //

#188                  // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.

#189                  //

#190 

 

设置驱动程序的兼容那些命令。

#191                  versionParameters->fCapabilities = (CAP_ATA_ID_CMD | CAP_ATAPI_ID_CMD | CAP_SMART_CMD);

#192 

#193                  //

#194                  // This is done because of how the IOCTL_SCSI_MINIPORT

#195                  // determines 'targetid's'. Disk.sys places the real target id value

#196                  // in the DeviceMap field. Once we do some parameter checking, the value passed

#197                  // back to the application will be determined.

#198                  //

#199 

 

获取设备号。

#200                  deviceNumber = versionParameters->bIDEDeviceMap;

#201 

 

如果设备不存在,就返回选择当前的设备出错。

#202                  if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||

#203                      (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {

#204 

#205                      status = SRB_STATUS_SELECTION_TIMEOUT;

#206                      break;

#207                  }

#208 

#209                  //

#210                  // NOTE: This will only set the bit

#211                  // corresponding to this drive's target id.

#212                  // The bit mask is as follows:

#213                  //

#214                  //     Sec Pri

#215                  //     S M S M

#216                  //     3 2 1 0

#217                  //

#218 

 

计算选择的设备号。

#219                  if (deviceExtension->NumberChannels == 1) {

#220                      if (deviceExtension->PrimaryAddress) {

#221                          deviceNumber = 1 << Srb->TargetId;

#222                      } else {

#223                          deviceNumber = 4 << Srb->TargetId;

#224                      }

#225                  } else {

#226                      deviceNumber = 1 << Srb->TargetId;

#227                  }

#228 

#229                  versionParameters->bIDEDeviceMap = deviceNumber;

#230 

#231                  status = SRB_STATUS_SUCCESS;

#232                  break;

#233              }

#234 

#235              case IOCTL_SCSI_MINIPORT_IDENTIFY: {

#236 

获取输出参数。

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

获取输入参数。

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

#239                  ULONG             i;

#240                  UCHAR             targetId;

#241 

#242 

 

如果是命令寄存器,就选择下面的处理。

#243                  if (cmdInParameters.irDriveRegs.bCommandReg == ID_CMD) {

#244 

#245                      //

#246                      // Extract the target.

#247                      //

#248 

 

获取目标驱动器设备。

#249                      targetId = cmdInParameters.bDriveNumber;

#250 

 

如果设备没有,或者设备不是ATAPI设备,就返回出错。

#251                  if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||

#252                       (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {

#253 

#254                          status = SRB_STATUS_SELECTION_TIMEOUT;

#255                          break;

#256                      }

#257 

#258                      //

#259                      // Zero the output buffer

#260                      //

#261 

 

清空输出缓冲区。

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

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

#264                      }

#265 

#266                      //

#267                      // Build status block.

#268                      //

#269 

 

设置输出参数的大小和设备状态。

#270                      cmdOutParameters->cBufferSize = IDENTIFY_BUFFER_SIZE;

#271                      cmdOutParameters->DriverStatus.bDriverError = 0;

#272                      cmdOutParameters->DriverStatus.bIDEError = 0;

#273 

#274                      //

#275                      // Extract the identify data from the device extension.

#276                      //

#277 

 

从设备获取标识数据给输出缓冲区。

#278                      ScsiPortMoveMemory (cmdOutParameters->bBuffer, &deviceExtension->IdentifyData[targetId], IDENTIFY_DATA_SIZE);

#279 

#280                      status = SRB_STATUS_SUCCESS;

#281 

#282 

#283                  } else {

#284                      status = SRB_STATUS_INVALID_REQUEST;

#285                  }

#286                  break;

#287              }

#288 

#289              case  IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS:

#290              case  IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS:

#291              case  IOCTL_SCSI_MINIPORT_ENABLE_SMART:

#292              case  IOCTL_SCSI_MINIPORT_DISABLE_SMART:

#293              case  IOCTL_SCSI_MINIPORT_RETURN_STATUS:

#294              case  IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE:

#295              case  IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:

#296              case  IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:

#297 

 

处理SMART相关的命令。

#298                  status = IdeSendSmartCommand(HwDeviceExtension,Srb);

#299                  break;

#300 

#301              default :

#302 

#303                  status = SRB_STATUS_INVALID_REQUEST;

#304                  break;

#305 

#306          }

#307 

#308          break;

#309 

#310      default:

#311 

#312          //

#313          // Indicate unsupported command.

#314          //

#315 

#316          status = SRB_STATUS_INVALID_REQUEST;

#317 

#318          break;

#319 

#320      } // end switch

#321 

#322      //

#323      // Check if command complete.

#324      //

#325 

 

检查命令是否完成。

#326      if (status != SRB_STATUS_PENDING) {

#327 

 

如果状态不是阻塞状态,说明命令已经处理完成。

#328          DebugPrint((2,

#329                     "AtapiStartIo: Srb %x complete with status %x/n",

#330                     Srb,

#331                     status));

#332 

#333          //

#334          // Clear current SRB.

#335          //

#336 

 

清除当前的SRB

#337          deviceExtension->CurrentSrb = NULL;

#338 

#339          //

#340          // Set status in SRB.

#341          //

#342 

 

设置SRB返回状态。

#343          Srb->SrbStatus = (UCHAR)status;

#344 

#345          //

#346          // Indicate command complete.

#347          //

#348 

 

通知这个SRB命令已经完成。

#349          ScsiPortNotification(RequestComplete,

#350                               deviceExtension,

#351                               Srb);

#352 

#353          //

#354          // Indicate ready for next request.

#355          //

#356 

 

准备处理下一个SRB

#357          ScsiPortNotification(NextRequest,

#358                               deviceExtension,

#359                               NULL);

#360      }

#361 

#362      return TRUE;

#363 

#364  } // end AtapiStartIo()

 

 

SENDCMDOUTPARAMS结构:

#001  #include <pshpack1.h>

#002  typedef struct _SENDCMDOUTPARAMS {

指明缓冲区里有多少字节数据。

#003     ULONG  cBufferSize;

驱动程序状态的结构。

#004     DRIVERSTATUS  DriverStatus;

保存从驱动器读取到的字节。

#005     UCHAR  bBuffer[1];

#006  } SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

#007  #include <poppack.h>

 

SENDCMDINPARAMS结构:

#001  #include <pshpack1.h>

#002  typedef struct _SENDCMDINPARAMS {

指明缓冲区里有多少字节。

#003     ULONG  cBufferSize;

保存IDE寄存器。

#004     IDEREGS  irDriveRegs;

驱动器序号。

#005     UCHAR  bDriveNumber;

#006     UCHAR  bReserved[3];

#007     ULONG  dwReserved[4];

保存数据的缓冲区。

#008     UCHAR  bBuffer[1];

#009  } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

#010  #include <poppack.h>

转载于:https://www.cnblogs.com/ajuanabc/archive/2009/10/20/2463674.html


http://www.ppmy.cn/news/545966.html

相关文章

atapi.sys 蓝屏 难度系数☆☆☆ ...

这得记录一下哈&#xff0c;有"损"学知识&#xff0c;哎.....如下。 刚才&#xff0c;在半岛博客上看视频&#xff0c;机子有点卡&#xff0c;我看了看cpu使用率也不高&#xff0c;内存也剩不少&#xff0c;这是怎么回事儿呢&#xff1f; 我就想&#xff0c;想着想着…

SATA-AHCI规范学习

目录 参考文献 基本概念 HBA AHCI HBA OOB(Out of Band)信号解析 PIO FPDMA TAG FIS(Frame Information Structure) PRD PIO Port Multiplier NCQ sht SATA Shadow Register SATA Registers SStatus register (SCR0) SError register (SCR1) SControl register (SCR2) SActi…

[原创]也学NTFS格式磁盘解析及atapi磁盘读写

[原创]也学NTFS格式磁盘解析及atapi磁盘读写 信息来源&#xff1a;邪恶八进制信息安全团队&#xff08; www.eviloctal.com&#xff09; 文章作者&#xff1a;Styxal 这个么……其实是某门课的大作业……自选题&#xff0c;于是就选了解析 NTFS格式 磁盘及Atapi读写&#xff0c…

INTELIED,PCIIEDX, ATAPI,Disk.sys的关系

INTEL的IDE控制器连接在PCI总线上&#xff0c;其驱动是INTELIED.sys(intel提供)PCIIEDX.sys(微软提供)&#xff0c;堆栈关系如下&#xff1a; !DevObj !DrvObj !DevExt ObjectName > 80e9b030 \Driver\IntelIde 80e9b0e8 PciIde0 80e931d0 \Driver\PC…

4399ATAPI讲解用例配置篇

API主要分为三部分&#xff0c;分为全局配置&#xff0c;用例配置和操作事件&#xff1b; 本章主要对用例配置的api进行文字说明&#xff1a; mapping&#xff1a; 用于类似PO封装中UI库,进行映射&#xff0c;减少脚本维护成本 guide&#xff1a; APP引导页面功能&#xff1b; …

ATA和ATAPI类型硬盘区别方法

ATA和ATAPI类型硬盘区别方法 2010-05-21 17:48 目前&#xff0c;计算机主板IDE控制器连接的硬盘有ATA&#xff08;AT Attachment&#xff09;类型和ATAPI&#xff08;AT Attachment Packet Interface&#xff09;类型。那么&#xff0c;软件程序BIOS或者Linux内核是如何才能识别…

学NTFS格式磁盘解析及atapi磁盘读写

链接&#xff1a;http://forum.eviloctal.com/thread-39947-1-1.html [原创]也学NTFS格式磁盘解析及atapi磁盘读写 信息来源&#xff1a;邪恶八进制信息安全团队&#xff08; www.eviloctal.com&#xff09; 文章作者&#xff1a;Styxal 这个么……其实是某门课的大作业……自选…

Hyper-V虚拟机启动报错:IDE/ATAPI 帐户没有足够的权限

Hyper-V在启动虚拟机时出现报错&#xff1a;“ide/atapi 账号没有足够的权限”。 原因&#xff1a;磁盘文件在的安全权限丢失导致。 解决方案&#xff1a; 1、【删除】 虚拟机/设置/IDE控制器/磁盘驱动器 2、【添加】虚拟机/设置/IDE控制器/