ReactOS  0.4.14-dev-608-gd495a4f
pcdisk.c
Go to the documentation of this file.
1 /*
2  * FreeLoader
3  * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 // #if defined(__i386__) || defined(_M_AMD64)
21 
22 #include <freeldr.h>
23 
24 #include <debug.h>
26 
27 #include <pshpack2.h>
28 
29 typedef struct
30 {
31  UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
32  UCHAR Reserved; // 01h - Reserved (0)
33  USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
34  USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
35  USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
36  ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
37 // ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
38  // used if DWORD at 04h is FFFFh:FFFFh
39  // Commented since some earlier BIOSes refuse to work with
40  // such extended structure
42 
43 typedef struct
44 {
45  UCHAR PacketSize; // 00h - Size of packet in bytes (13h)
46  UCHAR MediaType; // 01h - Boot media type (see #00282)
47  UCHAR DriveNumber; /* 02h - Drive number:
48  * 00h Floppy image
49  * 80h Bootable hard disk
50  * 81h-FFh Nonbootable or no emulation
51  */
52  UCHAR Controller; // 03h - CD-ROM controller number
53  ULONG LBAImage; // 04h - Logical Block Address of disk image to emulate
54  USHORT DeviceSpec; /* 08h - Device specification (see also #00282)
55  * (IDE) Bit 0:
56  * Drive is slave instead of master
57  * (SCSI) Bits 7-0:
58  * LUN and PUN
59  * Bits 15-8:
60  * Bus number
61  */
62  USHORT Buffer; // 0Ah - Segment of 3K buffer for caching CD-ROM reads
63  USHORT LoadSeg; // 0Ch - Load segment for initial boot image.
64  // If 0000h, load at segment 07C0h.
65  USHORT SectorCount; // 0Eh - Number of 512-byte virtual sectors to load
66  // (only valid for AH=4Ch).
67  UCHAR CHSGeometry[3]; /* 10h - Low byte of cylinder count (for INT 13/AH=08h)
68  * 11h - Sector count, high bits of cylinder count (for INT 13/AH=08h)
69  * 12h - Head count (for INT 13/AH=08h)
70  */
73 
74 #include <poppack.h>
75 
76 /* DISK IO ERROR SUPPORT *****************************************************/
77 
78 static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors.
79 
81 {
82  /* Set the reference count */
83  if (bShowError) ++lReportError;
84  else --lReportError;
85  return lReportError;
86 }
87 
89 {
90  switch (ErrorCode)
91  {
92  case 0x00: return "no error";
93  case 0x01: return "bad command passed to driver";
94  case 0x02: return "address mark not found or bad sector";
95  case 0x03: return "diskette write protect error";
96  case 0x04: return "sector not found";
97  case 0x05: return "fixed disk reset failed";
98  case 0x06: return "diskette changed or removed";
99  case 0x07: return "bad fixed disk parameter table";
100  case 0x08: return "DMA overrun";
101  case 0x09: return "DMA access across 64k boundary";
102  case 0x0A: return "bad fixed disk sector flag";
103  case 0x0B: return "bad fixed disk cylinder";
104  case 0x0C: return "unsupported track/invalid media";
105  case 0x0D: return "invalid number of sectors on fixed disk format";
106  case 0x0E: return "fixed disk controlled data address mark detected";
107  case 0x0F: return "fixed disk DMA arbitration level out of range";
108  case 0x10: return "ECC/CRC error on disk read";
109  case 0x11: return "recoverable fixed disk data error, data fixed by ECC";
110  case 0x20: return "controller error (NEC for floppies)";
111  case 0x40: return "seek failure";
112  case 0x80: return "time out, drive not ready";
113  case 0xAA: return "fixed disk drive not ready";
114  case 0xBB: return "fixed disk undefined error";
115  case 0xCC: return "fixed disk write fault on selected drive";
116  case 0xE0: return "fixed disk status error/Error reg = 0";
117  case 0xFF: return "sense operation failed";
118 
119  default: return "unknown error code";
120  }
121 }
122 
123 static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
124 {
125  CHAR ErrorCodeString[200];
126 
127  if (lReportError < 0)
128  return;
129 
130  sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s",
132 
133  TRACE("%s\n", ErrorCodeString);
134 
135  UiMessageBox(ErrorCodeString);
136 }
137 
138 /* FUNCTIONS *****************************************************************/
139 
141 {
142  REGS RegsIn, RegsOut;
143 
144  WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
145 
146  /*
147  * BIOS Int 13h, function 0 - Reset disk system
148  * AH = 00h
149  * DL = drive (if bit 7 is set both hard disks and floppy disks reset)
150  * Return:
151  * AH = status
152  * CF clear if successful
153  * CF set on error
154  */
155  RegsIn.b.ah = 0x00;
156  RegsIn.b.dl = DriveNumber;
157 
158  /* Reset the disk controller */
159  Int386(0x13, &RegsIn, &RegsOut);
160 
161  return INT386_SUCCESS(RegsOut);
162 }
163 
165 {
166  REGS RegsIn, RegsOut;
167  ULONG RetryCount;
169 
170  TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
171  ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
172 
173  /* Setup disk address packet */
174  RtlZeroMemory(Packet, sizeof(*Packet));
175  Packet->PacketSize = sizeof(*Packet);
176  Packet->Reserved = 0;
177  Packet->LBABlockCount = (USHORT)SectorCount;
178  ASSERT(Packet->LBABlockCount == SectorCount);
179  Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F;
180  Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
181  Packet->LBAStartBlock = SectorNumber;
182 
183  /*
184  * BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
185  * Return:
186  * CF clear if successful
187  * AH = 00h
188  * CF set on error
189  * AH = error code
190  * Disk address packet's block count field set to the
191  * number of blocks successfully transferred.
192  */
193  RegsIn.b.ah = 0x42; // Subfunction 42h
194  RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
195  RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
196  RegsIn.w.si = BIOSCALLBUFOFFSET;
197 
198  /* Retry 3 times */
199  for (RetryCount=0; RetryCount<3; RetryCount++)
200  {
201  Int386(0x13, &RegsIn, &RegsOut);
202 
203  /* If it worked return TRUE */
204  if (INT386_SUCCESS(RegsOut))
205  {
206  return TRUE;
207  }
208  /* If it was a corrected ECC error then the data is still good */
209  else if (RegsOut.b.ah == 0x11)
210  {
211  return TRUE;
212  }
213  /* If it failed then do the next retry */
214  else
215  {
216  DiskResetController(DriveNumber);
217  continue;
218  }
219  }
220 
221  /* If we get here then the read failed */
222  DiskError("Disk Read Failed in LBA mode", RegsOut.b.ah);
223  ERR("Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
224  RegsOut.b.ah, DiskGetErrorCodeString(RegsOut.b.ah),
225  DriveNumber, SectorNumber, SectorCount);
226 
227  return FALSE;
228 }
229 
231 {
232  UCHAR PhysicalSector;
233  UCHAR PhysicalHead;
234  ULONG PhysicalTrack;
235  GEOMETRY DriveGeometry;
236  ULONG NumberOfSectorsToRead;
237  REGS RegsIn, RegsOut;
238  ULONG RetryCount;
239 
240  TRACE("PcDiskReadLogicalSectorsCHS()\n");
241 
242  /* Get the drive geometry */
243  //
244  // TODO: Cache this information for the given drive.
245  //
246  if (!PcDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
247  DriveGeometry.Sectors == 0 || DriveGeometry.Heads == 0)
248  {
249  return FALSE;
250  }
251 
252  while (SectorCount)
253  {
254  /*
255  * Calculate the physical disk offsets.
256  * Note: DriveGeometry.Sectors < 64
257  */
258  PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
259  PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
260  PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
261 
262  /* Calculate how many sectors we need to read this round */
263  if (PhysicalSector > 1)
264  {
265  if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
266  NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
267  else
268  NumberOfSectorsToRead = SectorCount;
269  }
270  else
271  {
272  if (SectorCount >= DriveGeometry.Sectors)
273  NumberOfSectorsToRead = DriveGeometry.Sectors;
274  else
275  NumberOfSectorsToRead = SectorCount;
276  }
277 
278  /* Make sure the read is within the geometry boundaries */
279  if ((PhysicalHead >= DriveGeometry.Heads) ||
280  (PhysicalTrack >= DriveGeometry.Cylinders) ||
281  ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
282  (PhysicalSector > DriveGeometry.Sectors))
283  {
284  DiskError("Disk read exceeds drive geometry limits.", 0);
285  return FALSE;
286  }
287 
288  /*
289  * BIOS Int 13h, function 2 - Read Disk Sectors
290  * AH = 02h
291  * AL = number of sectors to read (must be nonzero)
292  * CH = low eight bits of cylinder number
293  * CL = sector number 1-63 (bits 0-5)
294  * high two bits of cylinder (bits 6-7, hard disk only)
295  * DH = head number
296  * DL = drive number (bit 7 set for hard disk)
297  * ES:BX -> data buffer
298  * Return:
299  * CF set on error
300  * if AH = 11h (corrected ECC error), AL = burst length
301  * CF clear if successful
302  * AH = status
303  * AL = number of sectors transferred
304  * (only valid if CF set for some BIOSes)
305  */
306  RegsIn.b.ah = 0x02;
307  RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
308  RegsIn.b.ch = (PhysicalTrack & 0xFF);
309  RegsIn.b.cl = (UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
310  RegsIn.b.dh = PhysicalHead;
311  RegsIn.b.dl = DriveNumber;
312  RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
313  RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
314 
315  /* Perform the read. Retry 3 times. */
316  for (RetryCount=0; RetryCount<3; RetryCount++)
317  {
318  Int386(0x13, &RegsIn, &RegsOut);
319 
320  /* If it worked break out */
321  if (INT386_SUCCESS(RegsOut))
322  {
323  break;
324  }
325  /* If it was a corrected ECC error then the data is still good */
326  else if (RegsOut.b.ah == 0x11)
327  {
328  break;
329  }
330  /* If it failed the do the next retry */
331  else
332  {
333  DiskResetController(DriveNumber);
334  continue;
335  }
336  }
337 
338  /* If we retried 3 times then fail */
339  if (RetryCount >= 3)
340  {
341  DiskError("Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.b.ah);
342  ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
343  RegsOut.b.ah, DiskGetErrorCodeString(RegsOut.b.ah),
344  DriveNumber, SectorNumber, SectorCount);
345  return FALSE;
346  }
347 
348  // I have learned that not all BIOSes return
349  // the sector read count in the AL register (at least mine doesn't)
350  // even if the sectors were read correctly. So instead
351  // of checking the sector read count we will rely solely
352  // on the carry flag being set on error
353 
354  Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
355  SectorCount -= NumberOfSectorsToRead;
356  SectorNumber += NumberOfSectorsToRead;
357  }
358 
359  return TRUE;
360 }
361 
363 {
364  static UCHAR LastDriveNumber = 0xff;
365  static BOOLEAN LastSupported;
366  REGS RegsIn, RegsOut;
367 
368  TRACE("DiskInt13ExtensionsSupported()\n");
369 
370  if (DriveNumber == LastDriveNumber)
371  {
372  TRACE("Using cached value %s for drive 0x%x\n",
373  LastSupported ? "TRUE" : "FALSE", DriveNumber);
374  return LastSupported;
375  }
376 
377  /*
378  * Some BIOSes report that extended disk access functions are not supported
379  * when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
380  * with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
381  * we can assume that all El Torito capable BIOSes support INT 13 extensions.
382  * We simply detect whether we're booting from CD by checking whether the drive
383  * number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
384  */
385  if (DriveNumber >= 0x8A)
386  {
387  LastSupported = TRUE;
388  return TRUE;
389  }
390 
391  LastDriveNumber = DriveNumber;
392 
393  /*
394  * IBM/MS INT 13 Extensions - INSTALLATION CHECK
395  * AH = 41h
396  * BX = 55AAh
397  * DL = drive (80h-FFh)
398  * Return:
399  * CF set on error (extensions not supported)
400  * AH = 01h (invalid function)
401  * CF clear if successful
402  * BX = AA55h if installed
403  * AH = major version of extensions
404  * 01h = 1.x
405  * 20h = 2.0 / EDD-1.0
406  * 21h = 2.1 / EDD-1.1
407  * 30h = EDD-3.0
408  * AL = internal use
409  * CX = API subset support bitmap
410  * DH = extension version (v2.0+ ??? -- not present in 1.x)
411  *
412  * Bitfields for IBM/MS INT 13 Extensions API support bitmap
413  * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
414  * Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
415  * Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
416  * extended drive parameter table is valid
417  * Bits 3-15 reserved
418  */
419  RegsIn.b.ah = 0x41;
420  RegsIn.w.bx = 0x55AA;
421  RegsIn.b.dl = DriveNumber;
422 
423  /* Reset the disk controller */
424  Int386(0x13, &RegsIn, &RegsOut);
425 
426  if (!INT386_SUCCESS(RegsOut))
427  {
428  /* CF set on error (extensions not supported) */
429  LastSupported = FALSE;
430  return FALSE;
431  }
432 
433  if (RegsOut.w.bx != 0xAA55)
434  {
435  /* BX = AA55h if installed */
436  LastSupported = FALSE;
437  return FALSE;
438  }
439 
440  if (!(RegsOut.w.cx & 0x0001))
441  {
442  /*
443  * CX = API subset support bitmap.
444  * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported.
445  */
446  DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n",
447  RegsOut.w.cx, DriveNumber);
448  LastSupported = FALSE;
449  return FALSE;
450  }
451 
452  LastSupported = TRUE;
453  return TRUE;
454 }
455 
457 {
458  BOOLEAN ExtensionsSupported;
459 
460  TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
461  DriveNumber, SectorNumber, SectorCount, Buffer);
462 
463  /*
464  * Check to see if it is a fixed disk drive.
465  * If so then check to see if Int13 extensions work.
466  * If they do then use them, otherwise default back to BIOS calls.
467  */
468  ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
469 
470  if ((DriveNumber >= 0x80) && ExtensionsSupported)
471  {
472  TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
473 
474  /* LBA is easy, nothing to calculate. Just do the read. */
475  return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
476  }
477  else
478  {
479  /* LBA is not supported default to the CHS calls */
480  return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
481  }
482 
483  return TRUE;
484 }
485 
486 #if defined(__i386__) || defined(_M_AMD64)
487 VOID __cdecl DiskStopFloppyMotor(VOID)
488 {
489  WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0x0C); // DOR_FDC_ENABLE | DOR_DMA_IO_INTERFACE_ENABLE
490 }
491 #endif // defined __i386__ || defined(_M_AMD64)
492 
494 {
495  REGS RegsIn, RegsOut;
497 
498  TRACE("DiskGetExtendedDriveParameters()\n");
499 
500  if (!DiskInt13ExtensionsSupported(DriveNumber))
501  return FALSE;
502 
503  /* Initialize transfer buffer */
504  *Ptr = BufferSize;
505 
506  /*
507  * BIOS Int 13h, function 48h - Get drive parameters
508  * AH = 48h
509  * DL = drive (bit 7 set for hard disk)
510  * DS:SI = result buffer
511  * Return:
512  * CF set on error
513  * AH = status (07h)
514  * CF clear if successful
515  * AH = 00h
516  * DS:SI -> result buffer
517  */
518  RegsIn.b.ah = 0x48;
519  RegsIn.b.dl = DriveNumber;
520  RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
521  RegsIn.w.si = BIOSCALLBUFOFFSET;
522 
523  /* Get drive parameters */
524  Int386(0x13, &RegsIn, &RegsOut);
525  if (!INT386_SUCCESS(RegsOut))
526  return FALSE;
527 
529 
530 #if DBG
531  TRACE("size of buffer: %x\n", Ptr[0]);
532  TRACE("information flags: %x\n", Ptr[1]);
533  TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]);
534  TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]);
535  TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]);
536  TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]);
537  TRACE("bytes per sector: %u\n", Ptr[12]);
538  if (Ptr[0] >= 0x1e)
539  {
540  TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]);
541  if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
542  {
543  PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
544  TRACE("SpecPtr: %x\n", SpecPtr);
545  TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]);
546  TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]);
547  TRACE("drive flags: %x\n", SpecPtr[4]);
548  TRACE("proprietary information: %x\n", SpecPtr[5]);
549  TRACE("IRQ for drive: %u\n", SpecPtr[6]);
550  TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
551  TRACE("DMA control: %x\n", SpecPtr[8]);
552  TRACE("programmed I/O control: %x\n", SpecPtr[9]);
553  TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]);
554  }
555  }
556  if (Ptr[0] >= 0x42)
557  {
558  TRACE("signature: %x\n", Ptr[15]);
559  }
560 #endif
561 
562  return TRUE;
563 }
564 
565 BOOLEAN
566 PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
567 {
568  EXTENDED_GEOMETRY ExtGeometry;
569  REGS RegsIn, RegsOut;
570  ULONG Cylinders;
571 
572  TRACE("DiskGetDriveGeometry()\n");
573 
574  /* Try to get the extended geometry first */
575  ExtGeometry.Size = sizeof(ExtGeometry);
576  if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
577  {
578  Geometry->Cylinders = ExtGeometry.Cylinders;
579  Geometry->Heads = ExtGeometry.Heads;
580  Geometry->Sectors = ExtGeometry.SectorsPerTrack;
581  Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
582  return TRUE;
583  }
584 
585  /*
586  * BIOS Int 13h, function 08h - Get drive parameters
587  * AH = 08h
588  * DL = drive (bit 7 set for hard disk)
589  * ES:DI = 0000h:0000h to guard against BIOS bugs
590  * Return:
591  * CF set on error
592  * AH = status (07h)
593  * CF clear if successful
594  * AH = 00h
595  * AL = 00h on at least some BIOSes
596  * BL = drive type (AT/PS2 floppies only)
597  * CH = low eight bits of maximum cylinder number
598  * CL = maximum sector number (bits 5-0)
599  * high two bits of maximum cylinder number (bits 7-6)
600  * DH = maximum head number
601  * DL = number of drives
602  * ES:DI -> drive parameter table (floppies only)
603  */
604  RegsIn.b.ah = 0x08;
605  RegsIn.b.dl = DriveNumber;
606  RegsIn.w.es = 0x0000;
607  RegsIn.w.di = 0x0000;
608 
609  /* Get drive parameters */
610  Int386(0x13, &RegsIn, &RegsOut);
611  if (!INT386_SUCCESS(RegsOut))
612  return FALSE;
613 
614  Cylinders = (RegsOut.b.cl & 0xC0) << 2;
615  Cylinders += RegsOut.b.ch;
616  Cylinders++;
617  Geometry->Cylinders = Cylinders;
618  Geometry->Heads = RegsOut.b.dh + 1;
619  Geometry->Sectors = RegsOut.b.cl & 0x3F;
620  Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
621 
622  return TRUE;
623 }
624 
625 ULONG
627 {
628  GEOMETRY Geometry;
629 
630  /* If LBA is supported then the block size will be 64 sectors (32k)
631  * If not then the block size is the size of one track. */
632  if (DiskInt13ExtensionsSupported(DriveNumber))
633  {
634  return 64;
635  }
636  /* Get the disk geometry. If this fails then we will
637  * just return 1 sector to be safe. */
638  else if (!PcDiskGetDriveGeometry(DriveNumber, &Geometry))
639  {
640  return 1;
641  }
642  else
643  {
644  return Geometry.Sectors;
645  }
646 }
647 
648 /* EOF */
BOOLEAN DiskResetController(UCHAR DriveNumber)
Definition: pcdisk.c:140
#define TRUE
Definition: types.h:120
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define __cdecl
Definition: accygwin.h:79
#define DbgPrint
Definition: loader.c:25
ULONGLONG LBAStartBlock
Definition: pcdisk.c:36
#define BIOSCALLBUFFER
Definition: x86common.h:12
struct I386_DISK_ADDRESS_PACKET * PI386_DISK_ADDRESS_PACKET
ULONG Cylinders
Definition: disk.h:26
USHORT TransferBufferSegment
Definition: pcdisk.c:35
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: pcdisk.c:164
#define WARN(fmt,...)
Definition: debug.h:111
DWORDREGS x
Definition: pcbios.h:148
unsigned short cx
Definition: pcbios.h:101
unsigned short es
Definition: pcbios.h:109
unsigned char ah
Definition: pcbios.h:120
ULONG Cylinders
Definition: disk.h:41
unsigned char dh
Definition: pcbios.h:129
uint32_t ULONG_PTR
Definition: typedefs.h:63
int __cdecl Int386(int ivec, REGS *in, REGS *out)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
ULONG PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
Definition: pcdisk.c:626
unsigned char dl
Definition: pcbios.h:128
#define BIOSCALLBUFSEGMENT
Definition: x86common.h:21
long LONG
Definition: pedump.c:60
#define INT386_SUCCESS(regs)
Definition: pcbios.h:167
ULONG SectorsPerTrack
Definition: disk.h:43
static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
Definition: pcdisk.c:88
DBG_DEFAULT_CHANNEL(DISK)
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:320
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
Definition: pcdisk.c:493
unsigned char BOOLEAN
BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
Definition: pcdisk.c:566
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: pcdisk.c:456
ULONG Sectors
Definition: disk.h:28
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:65
#define BufferSize
Definition: classpnp.h:419
#define BIOSCALLBUFOFFSET
Definition: x86common.h:22
unsigned char ch
Definition: pcbios.h:126
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char cl
Definition: pcbios.h:125
BYTEREGS b
Definition: pcbios.h:151
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char al
Definition: pcbios.h:119
static BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
Definition: pcdisk.c:362
ULONG SectorCount
Definition: part_xbox.c:32
USHORT Size
Definition: disk.h:39
#define ERR(fmt,...)
Definition: debug.h:109
LONG DiskReportError(BOOLEAN bShowError)
Definition: pcdisk.c:80
ULONG BytesPerSector
Definition: disk.h:29
USHORT BytesPerSector
Definition: disk.h:45
struct I386_CDROM_SPEC_PACKET * PI386_CDROM_SPEC_PACKET
unsigned short USHORT
Definition: pedump.c:61
ULONG Heads
Definition: disk.h:42
Definition: disk.h:24
unsigned short bx
Definition: pcbios.h:100
unsigned int * PULONG
Definition: retypes.h:1
static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
Definition: pcdisk.c:123
unsigned short si
Definition: pcbios.h:104
unsigned int ULONG
Definition: retypes.h:1
Definition: pcbios.h:146
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
static LONG lReportError
Definition: pcdisk.c:78
const char * PCSTR
Definition: typedefs.h:51
static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: pcdisk.c:230
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
USHORT TransferBufferOffset
Definition: pcdisk.c:34
unsigned short * PUSHORT
Definition: retypes.h:2
unsigned short di
Definition: pcbios.h:105
WORDREGS w
Definition: pcbios.h:150
unsigned short ds
Definition: pcbios.h:88
ULONG Heads
Definition: disk.h:27