微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

reactos操作系统实现(110)

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.jb51.cc/react/308416.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐