Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenatapi.h
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Storage Stack 00003 * LICENSE: DDK - see license.txt in the root dir 00004 * FILE: drivers/storage/atapi/atapi.h 00005 * PURPOSE: ATAPI IDE miniport driver 00006 * PROGRAMMERS: Based on a source code sample from Microsoft NT4 DDK 00007 */ 00008 00009 #include <srb.h> 00010 #include <scsi.h> 00011 00012 // 00013 // IDE register definition 00014 // 00015 00016 typedef struct _IDE_REGISTERS_1 { 00017 USHORT Data; 00018 UCHAR BlockCount; 00019 UCHAR BlockNumber; 00020 UCHAR CylinderLow; 00021 UCHAR CylinderHigh; 00022 UCHAR DriveSelect; 00023 UCHAR Command; 00024 } IDE_REGISTERS_1, *PIDE_REGISTERS_1; 00025 00026 typedef struct _IDE_REGISTERS_2 { 00027 UCHAR AlternateStatus; 00028 UCHAR DriveAddress; 00029 } IDE_REGISTERS_2, *PIDE_REGISTERS_2; 00030 00031 typedef struct _IDE_REGISTERS_3 { 00032 ULONG Data; 00033 UCHAR Others[4]; 00034 } IDE_REGISTERS_3, *PIDE_REGISTERS_3; 00035 00036 // 00037 // Device Extension Device Flags 00038 // 00039 00040 #define DFLAGS_DEVICE_PRESENT 0x0001 // Indicates that some device is present. 00041 #define DFLAGS_ATAPI_DEVICE 0x0002 // Indicates whether Atapi commands can be used. 00042 #define DFLAGS_TAPE_DEVICE 0x0004 // Indicates whether this is a tape device. 00043 #define DFLAGS_INT_DRQ 0x0008 // Indicates whether device interrupts as DRQ is set after 00044 // receiving Atapi Packet Command 00045 #define DFLAGS_REMOVABLE_DRIVE 0x0010 // Indicates that the drive has the 'removable' bit set in 00046 // identify data (offset 128) 00047 #define DFLAGS_MEDIA_STATUS_ENABLED 0x0020 // Media status notification enabled 00048 #define DFLAGS_ATAPI_CHANGER 0x0040 // Indicates atapi 2.5 changer present. 00049 #define DFLAGS_SANYO_ATAPI_CHANGER 0x0080 // Indicates multi-platter device, not conforming to the 2.5 spec. 00050 #define DFLAGS_CHANGER_INITED 0x0100 // Indicates that the init path for changers has already been done. 00051 // 00052 // Used to disable 'advanced' features. 00053 // 00054 00055 #define MAX_ERRORS 4 00056 00057 // 00058 // ATAPI command definitions 00059 // 00060 00061 #define ATAPI_MODE_SENSE 0x5A 00062 #define ATAPI_MODE_SELECT 0x55 00063 #define ATAPI_FORMAT_UNIT 0x24 00064 00065 // 00066 // ATAPI Command Descriptor Block 00067 // 00068 00069 typedef struct _MODE_SENSE_10 { 00070 UCHAR OperationCode; 00071 UCHAR Reserved1; 00072 UCHAR PageCode : 6; 00073 UCHAR Pc : 2; 00074 UCHAR Reserved2[4]; 00075 UCHAR ParameterListLengthMsb; 00076 UCHAR ParameterListLengthLsb; 00077 UCHAR Reserved3[3]; 00078 } MODE_SENSE_10, *PMODE_SENSE_10; 00079 00080 typedef struct _MODE_SELECT_10 { 00081 UCHAR OperationCode; 00082 UCHAR Reserved1 : 4; 00083 UCHAR PFBit : 1; 00084 UCHAR Reserved2 : 3; 00085 UCHAR Reserved3[5]; 00086 UCHAR ParameterListLengthMsb; 00087 UCHAR ParameterListLengthLsb; 00088 UCHAR Reserved4[3]; 00089 } MODE_SELECT_10, *PMODE_SELECT_10; 00090 00091 typedef struct _MODE_PARAMETER_HEADER_10 { 00092 UCHAR ModeDataLengthMsb; 00093 UCHAR ModeDataLengthLsb; 00094 UCHAR MediumType; 00095 UCHAR Reserved[5]; 00096 }MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10; 00097 00098 // 00099 // IDE command definitions 00100 // 00101 00102 #define IDE_COMMAND_ATAPI_RESET 0x08 00103 #define IDE_COMMAND_RECALIBRATE 0x10 00104 #define IDE_COMMAND_READ 0x20 00105 #define IDE_COMMAND_WRITE 0x30 00106 #define IDE_COMMAND_VERIFY 0x40 00107 #define IDE_COMMAND_SEEK 0x70 00108 #define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 00109 #define IDE_COMMAND_ATAPI_PACKET 0xA0 00110 #define IDE_COMMAND_ATAPI_IDENTIFY 0xA1 00111 #define IDE_COMMAND_READ_MULTIPLE 0xC4 00112 #define IDE_COMMAND_WRITE_MULTIPLE 0xC5 00113 #define IDE_COMMAND_SET_MULTIPLE 0xC6 00114 #define IDE_COMMAND_READ_DMA 0xC8 00115 #define IDE_COMMAND_WRITE_DMA 0xCA 00116 #define IDE_COMMAND_GET_MEDIA_STATUS 0xDA 00117 #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF 00118 #define IDE_COMMAND_IDENTIFY 0xEC 00119 #define IDE_COMMAND_MEDIA_EJECT 0xED 00120 00121 // 00122 // IDE status definitions 00123 // 00124 00125 #define IDE_STATUS_ERROR 0x01 00126 #define IDE_STATUS_INDEX 0x02 00127 #define IDE_STATUS_CORRECTED_ERROR 0x04 00128 #define IDE_STATUS_DRQ 0x08 00129 #define IDE_STATUS_DSC 0x10 00130 #define IDE_STATUS_DRDY 0x40 00131 #define IDE_STATUS_IDLE 0x50 00132 #define IDE_STATUS_BUSY 0x80 00133 00134 // 00135 // IDE drive select/head definitions 00136 // 00137 00138 #define IDE_DRIVE_SELECT_1 0xA0 00139 #define IDE_DRIVE_SELECT_2 0x10 00140 00141 // 00142 // IDE drive control definitions 00143 // 00144 00145 #define IDE_DC_DISABLE_INTERRUPTS 0x02 00146 #define IDE_DC_RESET_CONTROLLER 0x04 00147 #define IDE_DC_REENABLE_CONTROLLER 0x00 00148 00149 // 00150 // IDE error definitions 00151 // 00152 00153 #define IDE_ERROR_BAD_BLOCK 0x80 00154 #define IDE_ERROR_DATA_ERROR 0x40 00155 #define IDE_ERROR_MEDIA_CHANGE 0x20 00156 #define IDE_ERROR_ID_NOT_FOUND 0x10 00157 #define IDE_ERROR_MEDIA_CHANGE_REQ 0x08 00158 #define IDE_ERROR_COMMAND_ABORTED 0x04 00159 #define IDE_ERROR_END_OF_MEDIA 0x02 00160 #define IDE_ERROR_ILLEGAL_LENGTH 0x01 00161 00162 // 00163 // ATAPI register definition 00164 // 00165 00166 typedef struct _ATAPI_REGISTERS_1 { 00167 USHORT Data; 00168 UCHAR InterruptReason; 00169 UCHAR Unused1; 00170 UCHAR ByteCountLow; 00171 UCHAR ByteCountHigh; 00172 UCHAR DriveSelect; 00173 UCHAR Command; 00174 } ATAPI_REGISTERS_1, *PATAPI_REGISTERS_1; 00175 00176 typedef struct _ATAPI_REGISTERS_2 { 00177 UCHAR AlternateStatus; 00178 UCHAR DriveAddress; 00179 } ATAPI_REGISTERS_2, *PATAPI_REGISTERS_2; 00180 00181 // 00182 // ATAPI interrupt reasons 00183 // 00184 00185 #define ATAPI_IR_COD 0x01 00186 #define ATAPI_IR_IO 0x02 00187 00188 // 00189 // IDENTIFY data 00190 // 00191 00192 typedef struct _IDENTIFY_DATA { 00193 USHORT GeneralConfiguration; // 00 00 00194 USHORT NumberOfCylinders; // 02 1 00195 USHORT Reserved1; // 04 2 00196 USHORT NumberOfHeads; // 06 3 00197 USHORT UnformattedBytesPerTrack; // 08 4 00198 USHORT UnformattedBytesPerSector; // 0A 5 00199 USHORT SectorsPerTrack; // 0C 6 00200 USHORT VendorUnique1[3]; // 0E 7-9 00201 USHORT SerialNumber[10]; // 14 10-19 00202 USHORT BufferType; // 28 20 00203 USHORT BufferSectorSize; // 2A 21 00204 USHORT NumberOfEccBytes; // 2C 22 00205 USHORT FirmwareRevision[4]; // 2E 23-26 00206 USHORT ModelNumber[20]; // 36 27-46 00207 UCHAR MaximumBlockTransfer; // 5E 47 00208 UCHAR VendorUnique2; // 5F 00209 USHORT DoubleWordIo; // 60 48 00210 USHORT Capabilities; // 62 49 00211 USHORT Reserved2; // 64 50 00212 UCHAR VendorUnique3; // 66 51 00213 UCHAR PioCycleTimingMode; // 67 00214 UCHAR VendorUnique4; // 68 52 00215 UCHAR DmaCycleTimingMode; // 69 00216 USHORT TranslationFieldsValid:1; // 6A 53 00217 USHORT Reserved3:15; 00218 USHORT NumberOfCurrentCylinders; // 6C 54 00219 USHORT NumberOfCurrentHeads; // 6E 55 00220 USHORT CurrentSectorsPerTrack; // 70 56 00221 ULONG CurrentSectorCapacity; // 72 57-58 00222 USHORT CurrentMultiSectorSetting; // 59 00223 ULONG UserAddressableSectors; // 60-61 00224 USHORT SingleWordDMASupport : 8; // 62 00225 USHORT SingleWordDMAActive : 8; 00226 USHORT MultiWordDMASupport : 8; // 63 00227 USHORT MultiWordDMAActive : 8; 00228 USHORT AdvancedPIOModes : 8; // 64 00229 USHORT Reserved4 : 8; 00230 USHORT MinimumMWXferCycleTime; // 65 00231 USHORT RecommendedMWXferCycleTime; // 66 00232 USHORT MinimumPIOCycleTime; // 67 00233 USHORT MinimumPIOCycleTimeIORDY; // 68 00234 USHORT Reserved5[2]; // 69-70 00235 USHORT ReleaseTimeOverlapped; // 71 00236 USHORT ReleaseTimeServiceCommand; // 72 00237 USHORT MajorRevision; // 73 00238 USHORT MinorRevision; // 74 00239 USHORT Reserved6[50]; // 75-126 00240 USHORT SpecialFunctionsEnabled; // 127 00241 USHORT Reserved7[128]; // 128-255 00242 } IDENTIFY_DATA, *PIDENTIFY_DATA; 00243 00244 // 00245 // Identify data without the Reserved4. 00246 // 00247 00248 typedef struct _IDENTIFY_DATA2 { 00249 USHORT GeneralConfiguration; // 00 00250 USHORT NumberOfCylinders; // 02 00251 USHORT Reserved1; // 04 00252 USHORT NumberOfHeads; // 06 00253 USHORT UnformattedBytesPerTrack; // 08 00254 USHORT UnformattedBytesPerSector; // 0A 00255 USHORT SectorsPerTrack; // 0C 00256 USHORT VendorUnique1[3]; // 0E 00257 USHORT SerialNumber[10]; // 14 00258 USHORT BufferType; // 28 00259 USHORT BufferSectorSize; // 2A 00260 USHORT NumberOfEccBytes; // 2C 00261 USHORT FirmwareRevision[4]; // 2E 00262 USHORT ModelNumber[20]; // 36 00263 UCHAR MaximumBlockTransfer; // 5E 00264 UCHAR VendorUnique2; // 5F 00265 USHORT DoubleWordIo; // 60 00266 USHORT Capabilities; // 62 00267 USHORT Reserved2; // 64 00268 UCHAR VendorUnique3; // 66 00269 UCHAR PioCycleTimingMode; // 67 00270 UCHAR VendorUnique4; // 68 00271 UCHAR DmaCycleTimingMode; // 69 00272 USHORT TranslationFieldsValid:1; // 6A 00273 USHORT Reserved3:15; 00274 USHORT NumberOfCurrentCylinders; // 6C 00275 USHORT NumberOfCurrentHeads; // 6E 00276 USHORT CurrentSectorsPerTrack; // 70 00277 ULONG CurrentSectorCapacity; // 72 00278 } IDENTIFY_DATA2, *PIDENTIFY_DATA2; 00279 00280 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA) 00281 00282 // 00283 // IDENTIFY capability bit definitions. 00284 // 00285 00286 #define IDENTIFY_CAPABILITIES_DMA_SUPPORTED 0x0100 00287 #define IDENTIFY_CAPABILITIES_LBA_SUPPORTED 0x0200 00288 00289 // 00290 // IDENTIFY DMA timing cycle modes. 00291 // 00292 00293 #define IDENTIFY_DMA_CYCLES_MODE_0 0x00 00294 #define IDENTIFY_DMA_CYCLES_MODE_1 0x01 00295 #define IDENTIFY_DMA_CYCLES_MODE_2 0x02 00296 00297 00298 typedef struct _BROKEN_CONTROLLER_INFORMATION { 00299 PCHAR VendorId; 00300 ULONG VendorIdLength; 00301 PCHAR DeviceId; 00302 ULONG DeviceIdLength; 00303 }BROKEN_CONTROLLER_INFORMATION, *PBROKEN_CONTROLLER_INFORMATION; 00304 00305 BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[] = { 00306 { "1095", 4, "0640", 4}, 00307 { "1039", 4, "0601", 4} 00308 }; 00309 00310 #define BROKEN_ADAPTERS (sizeof(BrokenAdapters) / sizeof(BROKEN_CONTROLLER_INFORMATION)) 00311 00312 typedef struct _NATIVE_MODE_CONTROLLER_INFORMATION { 00313 PCHAR VendorId; 00314 ULONG VendorIdLength; 00315 PCHAR DeviceId; 00316 ULONG DeviceIdLength; 00317 }NATIVE_MODE_CONTROLLER_INFORMATION, *PNATIVE_MODE_CONTROLLER_INFORMATION; 00318 00319 NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = { 00320 { "10ad", 4, "0105", 4} 00321 }; 00322 #define NUM_NATIVE_MODE_ADAPTERS (sizeof(NativeModeAdapters) / sizeof(NATIVE_MODE_CONTROLLER_INFORMATION)) 00323 00324 // 00325 // Beautification macros 00326 // 00327 00328 #define GetStatus(BaseIoAddress, Status) \ 00329 Status = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus); 00330 00331 #define GetBaseStatus(BaseIoAddress, Status) \ 00332 Status = ScsiPortReadPortUchar(&BaseIoAddress->Command); 00333 00334 #define WriteCommand(BaseIoAddress, Command) \ 00335 ScsiPortWritePortUchar(&BaseIoAddress->Command, Command); 00336 00337 00338 00339 #define ReadBuffer(BaseIoAddress, Buffer, Count) \ 00340 ScsiPortReadPortBufferUshort(&BaseIoAddress->Data, \ 00341 Buffer, \ 00342 Count); 00343 00344 #define WriteBuffer(BaseIoAddress, Buffer, Count) \ 00345 ScsiPortWritePortBufferUshort(&BaseIoAddress->Data, \ 00346 Buffer, \ 00347 Count); 00348 00349 #define ReadBuffer2(BaseIoAddress, Buffer, Count) \ 00350 ScsiPortReadPortBufferUlong(&BaseIoAddress->Data, \ 00351 Buffer, \ 00352 Count); 00353 00354 #define WriteBuffer2(BaseIoAddress, Buffer, Count) \ 00355 ScsiPortWritePortBufferUlong(&BaseIoAddress->Data, \ 00356 Buffer, \ 00357 Count); 00358 00359 #define WaitOnBusy(BaseIoAddress, Status) \ 00360 { \ 00361 ULONG i; \ 00362 for (i=0; i<20000; i++) { \ 00363 GetStatus(BaseIoAddress, Status); \ 00364 if (Status & IDE_STATUS_BUSY) { \ 00365 ScsiPortStallExecution(150); \ 00366 continue; \ 00367 } else { \ 00368 break; \ 00369 } \ 00370 } \ 00371 } 00372 00373 #define WaitOnBaseBusy(BaseIoAddress, Status) \ 00374 { \ 00375 ULONG i; \ 00376 for (i=0; i<20000; i++) { \ 00377 GetBaseStatus(BaseIoAddress, Status); \ 00378 if (Status & IDE_STATUS_BUSY) { \ 00379 ScsiPortStallExecution(150); \ 00380 continue; \ 00381 } else { \ 00382 break; \ 00383 } \ 00384 } \ 00385 } 00386 00387 #define WaitForDrq(BaseIoAddress, Status) \ 00388 { \ 00389 ULONG i; \ 00390 for (i=0; i<1000; i++) { \ 00391 GetStatus(BaseIoAddress, Status); \ 00392 if (Status & IDE_STATUS_BUSY) { \ 00393 ScsiPortStallExecution(100); \ 00394 } else if (Status & IDE_STATUS_DRQ) { \ 00395 break; \ 00396 } else { \ 00397 ScsiPortStallExecution(200); \ 00398 } \ 00399 } \ 00400 } 00401 00402 00403 #define WaitShortForDrq(BaseIoAddress, Status) \ 00404 { \ 00405 ULONG i; \ 00406 for (i=0; i<2; i++) { \ 00407 GetStatus(BaseIoAddress, Status); \ 00408 if (Status & IDE_STATUS_BUSY) { \ 00409 ScsiPortStallExecution(100); \ 00410 } else if (Status & IDE_STATUS_DRQ) { \ 00411 break; \ 00412 } else { \ 00413 ScsiPortStallExecution(100); \ 00414 } \ 00415 } \ 00416 } 00417 00418 #define AtapiSoftReset(BaseIoAddress,DeviceNumber) \ 00419 {\ 00420 UCHAR statusByte; \ 00421 ULONG i = 1000*1000;\ 00422 ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)(((DeviceNumber & 0x1) << 4) | 0xA0)); \ 00423 ScsiPortStallExecution(500);\ 00424 ScsiPortWritePortUchar(&BaseIoAddress->Command, IDE_COMMAND_ATAPI_RESET); \ 00425 while ((ScsiPortReadPortUchar(&BaseIoAddress->Command) & IDE_STATUS_BUSY) && i--)\ 00426 ScsiPortStallExecution(30);\ 00427 ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)((DeviceNumber << 4) | 0xA0)); \ 00428 WaitOnBusy( ((PIDE_REGISTERS_2)((PUCHAR)BaseIoAddress + 0x206)), statusByte); \ 00429 ScsiPortStallExecution(500);\ 00430 } 00431 00432 #define IdeHardReset(BaseIoAddress,result) \ 00433 {\ 00434 UCHAR statusByte;\ 00435 ULONG i;\ 00436 ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_RESET_CONTROLLER );\ 00437 ScsiPortStallExecution(50 * 1000);\ 00438 ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_REENABLE_CONTROLLER);\ 00439 for (i = 0; i < 1000 * 1000; i++) {\ 00440 statusByte = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus);\ 00441 if (statusByte != IDE_STATUS_IDLE && statusByte != 0x0) {\ 00442 ScsiPortStallExecution(5);\ 00443 } else {\ 00444 break;\ 00445 }\ 00446 }\ 00447 if (i == 1000*1000) {\ 00448 result = FALSE;\ 00449 }\ 00450 result = TRUE;\ 00451 } 00452 00453 #define IS_RDP(OperationCode)\ 00454 ((OperationCode == SCSIOP_ERASE)||\ 00455 (OperationCode == SCSIOP_LOAD_UNLOAD)||\ 00456 (OperationCode == SCSIOP_LOCATE)||\ 00457 (OperationCode == SCSIOP_REWIND) ||\ 00458 (OperationCode == SCSIOP_SPACE)||\ 00459 (OperationCode == SCSIOP_SEEK)||\ 00460 (OperationCode == SCSIOP_WRITE_FILEMARKS)) 00461 Generated on Thu May 24 2012 04:28:56 for ReactOS by
1.7.6.1
|