ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

xboxdisk.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.