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() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |