reactos操作系统实现(108)
AtapiHwInitialize函数初始化不是ATAPT设备,设置它支持多块传送。接着判断那些设备是CD-ROM设备,还清除忙状态。具体实现代码如下: #001 BOOLEAN #002 NTAPI #003 AtapiHwInitialize( #004 IN PVOID HwDeviceExtension #005 ) #006 #007 /*++ #008 #009 Routine Description: #010 #011 Arguments: #012 #013 HwDeviceExtension - HBA miniport driver's adapter data storage #014 #015 Return Value: #016 #017 TRUE - if initialization successful. #018 FALSE - if initialization unsuccessful. #019 #020 --*/ #021 #022 { #023 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension; #024 PIDE_REGISTERS_1 baseIoAddress; #025 ULONG i; #026 UCHAR statusByte,errorByte; #027 #028
对于两个通道4个IDE控制器进行初始化。 #029 for (i = 0; i < 4; i++) {
如果IDE的设备存在,就进行处理。 #030 if (deviceExtension->DeviceFlags[i] & DFLAGS_DEVICE_PRESENT) { #031
如果这个设备不是ATAPI设备,就进入下面初始化。 #032 if (!(deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE)) { #033 #034 // #035 // Enable media status notification #036 // #037
获取基地址。 #038 baseIoAddress = deviceExtension->BaseIoAddress1[i >> 1]; #039
设置媒体感知。 #040 IdeMediaStatus(TRUE,HwDeviceExtension,i); #041
如果支持多块传送,就设置多块传送参数。 #042 // #043 // If supported,setup Multi-block transfers. #044 // #045 if (deviceExtension->MaximumBlockXfer[i]) { #046 #047 // #048 // Select the device. #049 // #050 #051 ScsiPortWritePortUchar(&baseIoAddress->DriveSelect, #052 (UCHAR)(((i & 0x1) << 4) | 0xA0)); #053 #054 // #055 // Setup sector count to reflect the # of blocks. #056 // #057 #058 ScsiPortWritePortUchar(&baseIoAddress->BlockCount, #059 deviceExtension->MaximumBlockXfer[i]); #060 #061 // #062 // Issue the command. #063 // #064
设置多块传送。 #065 ScsiPortWritePortUchar(&baseIoAddress->Command, #066 IDE_COMMAND_SET_MULTIPLE); #067 #068 // #069 // Wait for busy to drop. #070 // #071 #072 WaitOnBaseBusy(baseIoAddress,statusByte); #073 #074 // #075 // Check for errors. Reset the value to 0 (disable MultiBlock) if the #076 // command was aborted. #077 // #078
如果设置多块传送命令失败,就设置为不支持多块传送。 #079 if (statusByte & IDE_STATUS_ERROR) { #080 #081 // #082 // Read the error register. #083 // #084 #085 errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress + 1); #086 #087 DebugPrint((1, #088 "AtapiHwInitialize: Error setting multiple mode. Status %x,error byte %x/n", #089 statusByte, #090 errorByte)); #091 // #092 // Adjust the devExt. value,if necessary. #093 // #094 #095 deviceExtension->MaximumBlockXfer[i] = 0; #096 #097 } else { #098 DebugPrint((2, #099 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d/n", #100 i, #101 deviceExtension->MaximumBlockXfer[i])); #102 } #103 } #104 } else if (!(deviceExtension->DeviceFlags[i] & DFLAGS_CHANGER_INITED)){
如果这个设备还没有初始化,就进行初始化设置。 #105 #106 ULONG j; #107 BOOLEAN isSanyo = FALSE; #108 UCHAR vendorId[26]; #109 #110 // #111 // Attempt to identify any special-case devices - psuedo-atapi changers,atapi changers,etc. #112 // #113
判断这个IDE设备是否为CR-ROM设备。 #114 for (j = 0; j < 13; j += 2) { #115 #116 // #117 // Build a buffer based on the identify data. #118 // #119 #120 vendorId[j] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j + 1]; #121 vendorId[j+1] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j]; #122 } #123
比较IDE设备标识是否为CD-ROM。 #124 if (!AtapiStringCmp ((PCHAR)vendorId,"CD-ROM CDR",11)) { #125 #126 // #127 // Inquiry string for older model had a '-',newer is '_' #128 // #129 #130 if (vendorId[12] == 'C') { #131 #132 // #133 // Torisan changer. Set the bit. This will be used in several places #134 // acting like 1) a multi-lun device and 2) building the 'special' TUR's. #135 // #136
设置设备已经初始化。 #137 deviceExtension->DeviceFlags[i] |= (DFLAGS_CHANGER_INITED | DFLAGS_SANYO_ATAPI_CHANGER); #138 deviceExtension->DiscsPresent[i] = 3; #139 isSanyo = TRUE; #140 } #141 } #142 } #143 #144 // #145 // We need to get our device ready for action before #146 // returning from this function #147 // #148 // According to the atapi spec 2.5 or 2.6,an atapi device #149 // clears its status BSY bit when it is ready for atapi commands. #150 // However,some devices (Panasonic SQ-TC500N) are still #151 // not ready even when the status BSY is clear. They don't react #152 // to atapi commands. #153 // #154 // Since there is really no other indication that tells us #155 // the drive is really ready for action. We are going to check BSY #156 // is clear and then just wait for an arbitrary amount of time! #157 //
下面开始清除忙状态。 #158 if (deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE) { #159 //PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[i >> 1]; #160 PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[i >> 1]; #161 ULONG waitCount; #162 #163 // have to get out of the loop sometime! #164 // 10000 * 100us = 1000,000us = 1000ms = 1s #165 waitCount = 10000; #166 GetStatus(baseIoAddress2,statusByte); #167 while ((statusByte & IDE_STATUS_BUSY) && waitCount) { #168 // #169 // Wait for Busy to drop. #170 // #171 ScsiPortStallExecution(100); #172 GetStatus(baseIoAddress2,statusByte); #173 waitCount--; #174 } #175 #176 // 5000 * 100us = 500,000us = 500ms = 0.5s #177 waitCount = 5000; #178 do { #179 ScsiPortStallExecution(100); #180 } while (waitCount--); #181 } #182 } #183 } #184 #185 return TRUE; #186 #187} // end AtapiHwInitialize() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |