Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxboxdisk.c
Go to the documentation of this file.
00001 /* $Id: xboxdisk.c 53542 2011-09-03 10:56:36Z rharabien $ 00002 * 00003 * FreeLoader 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 * 00019 * Note: mostly ripped from atapi.c 00020 * Some of this code was based on knowledge and/or code developed 00021 * by the Xbox Linux group: http://www.xbox-linux.org 00022 * 00023 */ 00024 00025 #include <freeldr.h> 00026 00027 #define NDEBUG 00028 #include <debug.h> 00029 00030 DBG_DEFAULT_CHANNEL(DISK); 00031 00032 #define XBOX_IDE_COMMAND_PORT 0x1f0 00033 #define XBOX_IDE_CONTROL_PORT 0x170 00034 00035 #define XBOX_SIGNATURE_SECTOR 3 00036 #define XBOX_SIGNATURE ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24)) 00037 00038 static struct 00039 { 00040 ULONG SectorCountBeforePartition; 00041 ULONG PartitionSectorCount; 00042 UCHAR SystemIndicator; 00043 } XboxPartitions[] = 00044 { 00045 /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */ 00046 { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */ 00047 { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */ 00048 { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */ 00049 { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */ 00050 { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */ 00051 }; 00052 00053 #define IDE_SECTOR_BUF_SZ 512 00054 #define IDE_MAX_POLL_RETRIES 100000 00055 #define IDE_MAX_BUSY_RETRIES 50000 00056 00057 /* Control Block offsets and masks */ 00058 #define IDE_REG_ALT_STATUS 0x0000 00059 #define IDE_REG_DEV_CNTRL 0x0000 /* device control register */ 00060 #define IDE_DC_SRST 0x04 /* drive reset (both drives) */ 00061 #define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */ 00062 #define IDE_REG_DRV_ADDR 0x0001 00063 00064 /* Command Block offsets and masks */ 00065 #define IDE_REG_DATA_PORT 0x0000 00066 #define IDE_REG_ERROR 0x0001 /* error register */ 00067 #define IDE_ER_AMNF 0x01 /* addr mark not found */ 00068 #define IDE_ER_TK0NF 0x02 /* track 0 not found */ 00069 #define IDE_ER_ABRT 0x04 /* command aborted */ 00070 #define IDE_ER_MCR 0x08 /* media change requested */ 00071 #define IDE_ER_IDNF 0x10 /* ID not found */ 00072 #define IDE_ER_MC 0x20 /* Media changed */ 00073 #define IDE_ER_UNC 0x40 /* Uncorrectable data error */ 00074 #define IDE_REG_PRECOMP 0x0001 00075 #define IDE_REG_SECTOR_CNT 0x0002 00076 #define IDE_REG_SECTOR_NUM 0x0003 00077 #define IDE_REG_CYL_LOW 0x0004 00078 #define IDE_REG_CYL_HIGH 0x0005 00079 #define IDE_REG_DRV_HEAD 0x0006 00080 #define IDE_DH_FIXED 0xA0 00081 #define IDE_DH_LBA 0x40 00082 #define IDE_DH_HDMASK 0x0F 00083 #define IDE_DH_DRV0 0x00 00084 #define IDE_DH_DRV1 0x10 00085 #define IDE_REG_STATUS 0x0007 00086 #define IDE_SR_BUSY 0x80 00087 #define IDE_SR_DRDY 0x40 00088 #define IDE_SR_WERR 0x20 00089 #define IDE_SR_DRQ 0x08 00090 #define IDE_SR_ERR 0x01 00091 #define IDE_REG_COMMAND 0x0007 00092 00093 /* IDE/ATA commands */ 00094 #define IDE_CMD_RESET 0x08 00095 #define IDE_CMD_READ 0x20 00096 #define IDE_CMD_READ_RETRY 0x21 00097 #define IDE_CMD_WRITE 0x30 00098 #define IDE_CMD_WRITE_RETRY 0x31 00099 #define IDE_CMD_PACKET 0xA0 00100 #define IDE_CMD_READ_MULTIPLE 0xC4 00101 #define IDE_CMD_WRITE_MULTIPLE 0xC5 00102 #define IDE_CMD_READ_DMA 0xC8 00103 #define IDE_CMD_WRITE_DMA 0xCA 00104 #define IDE_CMD_FLUSH_CACHE 0xE7 00105 #define IDE_CMD_FLUSH_CACHE_EXT 0xEA 00106 #define IDE_CMD_IDENT_ATA_DRV 0xEC 00107 #define IDE_CMD_IDENT_ATAPI_DRV 0xA1 00108 #define IDE_CMD_GET_MEDIA_STATUS 0xDA 00109 00110 /* 00111 * Access macros for command registers 00112 * Each macro takes an address of the command port block, and data 00113 */ 00114 #define IDEReadError(Address) \ 00115 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR))) 00116 #define IDEWritePrecomp(Address, Data) \ 00117 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data))) 00118 #define IDEReadSectorCount(Address) \ 00119 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT))) 00120 #define IDEWriteSectorCount(Address, Data) \ 00121 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data))) 00122 #define IDEReadSectorNum(Address) \ 00123 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM))) 00124 #define IDEWriteSectorNum(Address, Data) \ 00125 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data))) 00126 #define IDEReadCylinderLow(Address) \ 00127 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW))) 00128 #define IDEWriteCylinderLow(Address, Data) \ 00129 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data))) 00130 #define IDEReadCylinderHigh(Address) \ 00131 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH))) 00132 #define IDEWriteCylinderHigh(Address, Data) \ 00133 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data))) 00134 #define IDEReadDriveHead(Address) \ 00135 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD))) 00136 #define IDEWriteDriveHead(Address, Data) \ 00137 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data))) 00138 #define IDEReadStatus(Address) \ 00139 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS))) 00140 #define IDEWriteCommand(Address, Data) \ 00141 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data))) 00142 #define IDEReadDMACommand(Address) \ 00143 (READ_PORT_UCHAR((PUCHAR)((Address)))) 00144 #define IDEWriteDMACommand(Address, Data) \ 00145 (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data))) 00146 #define IDEReadDMAStatus(Address) \ 00147 (READ_PORT_UCHAR((PUCHAR)((Address) + 2))) 00148 #define IDEWriteDMAStatus(Address, Data) \ 00149 (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data))) 00150 #define IDEWritePRDTable(Address, Data) \ 00151 (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data))) 00152 00153 /* 00154 * Data block read and write commands 00155 */ 00156 #define IDEReadBlock(Address, Buffer, Count) \ 00157 (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) 00158 #define IDEWriteBlock(Address, Buffer, Count) \ 00159 (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) 00160 00161 #define IDEReadBlock32(Address, Buffer, Count) \ 00162 (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) 00163 #define IDEWriteBlock32(Address, Buffer, Count) \ 00164 (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) 00165 00166 #define IDEReadWord(Address) \ 00167 (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT))) 00168 00169 /* 00170 * Access macros for control registers 00171 * Each macro takes an address of the control port blank and data 00172 */ 00173 #define IDEReadAltStatus(Address) \ 00174 (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS))) 00175 #define IDEWriteDriveControl(Address, Data) \ 00176 (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data))) 00177 00178 /* IDE_DRIVE_IDENTIFY */ 00179 00180 typedef struct _IDE_DRIVE_IDENTIFY 00181 { 00182 USHORT ConfigBits; /*00*/ 00183 USHORT LogicalCyls; /*01*/ 00184 USHORT Reserved02; /*02*/ 00185 USHORT LogicalHeads; /*03*/ 00186 USHORT BytesPerTrack; /*04*/ 00187 USHORT BytesPerSector; /*05*/ 00188 USHORT SectorsPerTrack; /*06*/ 00189 UCHAR InterSectorGap; /*07*/ 00190 UCHAR InterSectorGapSize; 00191 UCHAR Reserved08H; /*08*/ 00192 UCHAR BytesInPLO; 00193 USHORT VendorUniqueCnt; /*09*/ 00194 char SerialNumber[20]; /*10*/ 00195 USHORT ControllerType; /*20*/ 00196 USHORT BufferSize; /*21*/ 00197 USHORT ECCByteCnt; /*22*/ 00198 char FirmwareRev[8]; /*23*/ 00199 char ModelNumber[40]; /*27*/ 00200 USHORT RWMultImplemented; /*47*/ 00201 USHORT DWordIo; /*48*/ 00202 USHORT Capabilities; /*49*/ 00203 #define IDE_DRID_STBY_SUPPORTED 0x2000 00204 #define IDE_DRID_IORDY_SUPPORTED 0x0800 00205 #define IDE_DRID_IORDY_DISABLE 0x0400 00206 #define IDE_DRID_LBA_SUPPORTED 0x0200 00207 #define IDE_DRID_DMA_SUPPORTED 0x0100 00208 USHORT Reserved50; /*50*/ 00209 USHORT MinPIOTransTime; /*51*/ 00210 USHORT MinDMATransTime; /*52*/ 00211 USHORT TMFieldsValid; /*53*/ 00212 USHORT TMCylinders; /*54*/ 00213 USHORT TMHeads; /*55*/ 00214 USHORT TMSectorsPerTrk; /*56*/ 00215 USHORT TMCapacityLo; /*57*/ 00216 USHORT TMCapacityHi; /*58*/ 00217 USHORT RWMultCurrent; /*59*/ 00218 USHORT TMSectorCountLo; /*60*/ 00219 USHORT TMSectorCountHi; /*61*/ 00220 USHORT DmaModes; /*62*/ 00221 USHORT MultiDmaModes; /*63*/ 00222 USHORT Reserved64[5]; /*64*/ 00223 USHORT Reserved69[2]; /*69*/ 00224 USHORT Reserved71[4]; /*71*/ 00225 USHORT MaxQueueDepth; /*75*/ 00226 USHORT Reserved76[4]; /*76*/ 00227 USHORT MajorRevision; /*80*/ 00228 USHORT MinorRevision; /*81*/ 00229 USHORT SupportedFeatures82; /*82*/ 00230 USHORT SupportedFeatures83; /*83*/ 00231 USHORT SupportedFeatures84; /*84*/ 00232 USHORT EnabledFeatures85; /*85*/ 00233 USHORT EnabledFeatures86; /*86*/ 00234 USHORT EnabledFeatures87; /*87*/ 00235 USHORT UltraDmaModes; /*88*/ 00236 USHORT Reserved89[11]; /*89*/ 00237 USHORT Max48BitAddress[4]; /*100*/ 00238 USHORT Reserved104[151]; /*104*/ 00239 USHORT Checksum; /*255*/ 00240 } IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY; 00241 00242 /* XboxDiskPolledRead 00243 * 00244 * DESCRIPTION: 00245 * Read a sector of data from the drive in a polled fashion. 00246 * 00247 * RUN LEVEL: 00248 * PASSIVE_LEVEL 00249 * 00250 * ARGUMENTS: 00251 * ULONG CommandPort Address of command port for drive 00252 * ULONG ControlPort Address of control port for drive 00253 * UCHAR PreComp Value to write to precomp register 00254 * UCHAR SectorCnt Value to write to sectorCnt register 00255 * UCHAR SectorNum Value to write to sectorNum register 00256 * UCHAR CylinderLow Value to write to CylinderLow register 00257 * UCHAR CylinderHigh Value to write to CylinderHigh register 00258 * UCHAR DrvHead Value to write to Drive/Head register 00259 * UCHAR Command Value to write to Command register 00260 * PVOID Buffer Buffer for output data 00261 * 00262 * RETURNS: 00263 * BOOLEAN: TRUE success, FALSE error 00264 */ 00265 00266 static BOOLEAN 00267 XboxDiskPolledRead(ULONG CommandPort, 00268 ULONG ControlPort, 00269 UCHAR PreComp, 00270 UCHAR SectorCnt, 00271 UCHAR SectorNum, 00272 UCHAR CylinderLow, 00273 UCHAR CylinderHigh, 00274 UCHAR DrvHead, 00275 UCHAR Command, 00276 PVOID Buffer) 00277 { 00278 ULONG SectorCount = 0; 00279 ULONG RetryCount; 00280 BOOLEAN Junk = FALSE; 00281 UCHAR Status; 00282 00283 /* Wait for BUSY to clear */ 00284 for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++) 00285 { 00286 Status = IDEReadStatus(CommandPort); 00287 if (!(Status & IDE_SR_BUSY)) 00288 { 00289 break; 00290 } 00291 StallExecutionProcessor(10); 00292 } 00293 TRACE("status=0x%x\n", Status); 00294 TRACE("waited %d usecs for busy to clear\n", RetryCount * 10); 00295 if (RetryCount >= IDE_MAX_BUSY_RETRIES) 00296 { 00297 WARN("Drive is BUSY for too long\n"); 00298 return FALSE; 00299 } 00300 00301 /* Write Drive/Head to select drive */ 00302 IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead); 00303 StallExecutionProcessor(500); 00304 00305 /* Disable interrupts */ 00306 IDEWriteDriveControl(ControlPort, IDE_DC_nIEN); 00307 StallExecutionProcessor(500); 00308 00309 /* Issue command to drive */ 00310 if (DrvHead & IDE_DH_LBA) 00311 { 00312 TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n", 00313 DrvHead & IDE_DH_DRV1 ? 1 : 0, 00314 ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum, 00315 SectorCnt, 00316 Command); 00317 } 00318 else 00319 { 00320 TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n", 00321 DrvHead & IDE_DH_DRV1 ? 1 : 0, 00322 CylinderHigh, 00323 CylinderLow, 00324 DrvHead & 0x0f, 00325 SectorNum, 00326 SectorCnt, 00327 Command); 00328 } 00329 00330 /* Setup command parameters */ 00331 IDEWritePrecomp(CommandPort, PreComp); 00332 IDEWriteSectorCount(CommandPort, SectorCnt); 00333 IDEWriteSectorNum(CommandPort, SectorNum); 00334 IDEWriteCylinderHigh(CommandPort, CylinderHigh); 00335 IDEWriteCylinderLow(CommandPort, CylinderLow); 00336 IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead); 00337 00338 /* Issue the command */ 00339 IDEWriteCommand(CommandPort, Command); 00340 StallExecutionProcessor(50); 00341 00342 /* wait for DRQ or error */ 00343 for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++) 00344 { 00345 Status = IDEReadStatus(CommandPort); 00346 if (!(Status & IDE_SR_BUSY)) 00347 { 00348 if (Status & IDE_SR_ERR) 00349 { 00350 IDEWriteDriveControl(ControlPort, 0); 00351 StallExecutionProcessor(50); 00352 IDEReadStatus(CommandPort); 00353 00354 return FALSE; 00355 } 00356 00357 if (Status & IDE_SR_DRQ) 00358 { 00359 break; 00360 } 00361 else 00362 { 00363 IDEWriteDriveControl(ControlPort, 0); 00364 StallExecutionProcessor(50); 00365 IDEReadStatus(CommandPort); 00366 00367 return FALSE; 00368 } 00369 } 00370 StallExecutionProcessor(10); 00371 } 00372 00373 /* timed out */ 00374 if (RetryCount >= IDE_MAX_POLL_RETRIES) 00375 { 00376 IDEWriteDriveControl(ControlPort, 0); 00377 StallExecutionProcessor(50); 00378 IDEReadStatus(CommandPort); 00379 00380 return FALSE; 00381 } 00382 00383 while (1) 00384 { 00385 /* Read data into buffer */ 00386 if (Junk == FALSE) 00387 { 00388 IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ); 00389 Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ); 00390 } 00391 else 00392 { 00393 UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ]; 00394 IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ); 00395 } 00396 SectorCount++; 00397 00398 /* Check for error or more sectors to read */ 00399 for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++) 00400 { 00401 Status = IDEReadStatus(CommandPort); 00402 if (!(Status & IDE_SR_BUSY)) 00403 { 00404 if (Status & IDE_SR_ERR) 00405 { 00406 IDEWriteDriveControl(ControlPort, 0); 00407 StallExecutionProcessor(50); 00408 IDEReadStatus(CommandPort); 00409 00410 return FALSE; 00411 } 00412 if (Status & IDE_SR_DRQ) 00413 { 00414 if (SectorCount >= SectorCnt) 00415 { 00416 TRACE("Buffer size exceeded!\n"); 00417 Junk = TRUE; 00418 } 00419 break; 00420 } 00421 else 00422 { 00423 if (SectorCount > SectorCnt) 00424 { 00425 TRACE("Read %lu sectors of junk!\n", 00426 SectorCount - SectorCnt); 00427 } 00428 IDEWriteDriveControl(ControlPort, 0); 00429 StallExecutionProcessor(50); 00430 IDEReadStatus(CommandPort); 00431 00432 return TRUE; 00433 } 00434 } 00435 } 00436 } 00437 } 00438 00439 BOOLEAN 00440 XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) 00441 { 00442 ULONG StartSector; 00443 UCHAR Count; 00444 00445 if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f)) 00446 { 00447 /* Xbox has only 1 IDE controller and no floppy */ 00448 WARN("Invalid drive number\n"); 00449 return FALSE; 00450 } 00451 00452 if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000))) 00453 { 00454 FIXME("48bit LBA required but not implemented\n"); 00455 return FALSE; 00456 } 00457 00458 StartSector = (ULONG) SectorNumber; 00459 while (0 < SectorCount) 00460 { 00461 Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255); 00462 if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT, 00463 XBOX_IDE_CONTROL_PORT, 00464 0, Count, 00465 StartSector & 0xff, 00466 (StartSector >> 8) & 0xff, 00467 (StartSector >> 16) & 0xff, 00468 ((StartSector >> 24) & 0x0f) | IDE_DH_LBA | 00469 (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1), 00470 IDE_CMD_READ, 00471 Buffer)) 00472 { 00473 return FALSE; 00474 } 00475 SectorCount -= Count; 00476 Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ); 00477 } 00478 00479 return TRUE; 00480 } 00481 00482 BOOLEAN 00483 XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry) 00484 { 00485 UCHAR SectorData[IDE_SECTOR_BUF_SZ]; 00486 00487 /* This is the Xbox, chances are that there is a Xbox-standard partitionless 00488 * disk in it so let's check that first */ 00489 00490 if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) && 00491 MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData)) 00492 { 00493 if (*((PULONG) SectorData) == XBOX_SIGNATURE) 00494 { 00495 memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY)); 00496 PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator; 00497 PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition; 00498 PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount; 00499 return TRUE; 00500 } 00501 } 00502 00503 /* No magic Xbox partitions. Maybe there's a MBR */ 00504 return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry); 00505 } 00506 00507 BOOLEAN 00508 XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry) 00509 { 00510 IDE_DRIVE_IDENTIFY DrvParms; 00511 ULONG i; 00512 BOOLEAN Atapi; 00513 00514 Atapi = FALSE; /* FIXME */ 00515 /* Get the Drive Identify block from drive or die */ 00516 if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT, 00517 XBOX_IDE_CONTROL_PORT, 00518 0, 00519 1, 00520 0, 00521 0, 00522 0, 00523 (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1), 00524 (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV), 00525 (PUCHAR) &DrvParms)) 00526 { 00527 ERR("XboxDiskPolledRead() failed\n"); 00528 return FALSE; 00529 } 00530 00531 Geometry->Cylinders = DrvParms.LogicalCyls; 00532 Geometry->Heads = DrvParms.LogicalHeads; 00533 Geometry->Sectors = DrvParms.SectorsPerTrack; 00534 00535 if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED)) 00536 { 00537 /* LBA ATA drives always have a sector size of 512 */ 00538 Geometry->BytesPerSector = 512; 00539 } 00540 else 00541 { 00542 TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector); 00543 if (DrvParms.BytesPerSector == 0) 00544 { 00545 Geometry->BytesPerSector = 512; 00546 } 00547 else 00548 { 00549 for (i = 1 << 15; i; i /= 2) 00550 { 00551 if (0 != (DrvParms.BytesPerSector & i)) 00552 { 00553 Geometry->BytesPerSector = i; 00554 break; 00555 } 00556 } 00557 } 00558 } 00559 TRACE("Cylinders %d\n", Geometry->Cylinders); 00560 TRACE("Heads %d\n", Geometry->Heads); 00561 TRACE("Sectors %d\n", Geometry->Sectors); 00562 TRACE("BytesPerSector %d\n", Geometry->BytesPerSector); 00563 00564 return TRUE; 00565 } 00566 00567 ULONG 00568 XboxDiskGetCacheableBlockCount(UCHAR DriveNumber) 00569 { 00570 /* 64 seems a nice number, it is used by the machpc code for LBA devices */ 00571 return 64; 00572 } 00573 00574 /* EOF */ Generated on Sat May 26 2012 04:17:53 for ReactOS by
1.7.6.1
|