Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

361 lines
9.0 KiB

  1. /*++
  2. Module Name:
  3. machine.c
  4. Author:
  5. Thomas Parslow [TomP] Feb-13-1990
  6. Reworked substantially in Tokyo 7-July-95 (tedm)
  7. Abstract:
  8. Machine/hardware dependent routines reside within this module/file.
  9. (Video is in disp_tm.c and disp_gm.c.)
  10. --*/
  11. #include "arccodes.h"
  12. #include "bootx86.h"
  13. #define FLOPPY_CONTROL_REGISTER (PUCHAR)0x3f2
  14. ARC_STATUS
  15. XferExtendedPhysicalDiskSectors(
  16. IN UCHAR Int13UnitNumber,
  17. IN ULONGLONG StartSector,
  18. IN USHORT SectorCount,
  19. PUCHAR Buffer,
  20. IN BOOLEAN Write
  21. )
  22. /*++
  23. Routine Description:
  24. Read or write disk sectors via extended int13.
  25. It is assumed that the caller has ensured that the transfer buffer is
  26. under the 1MB line, that the sector run does not cross a 64K boundary,
  27. etc.
  28. This routine does not check whether extended int13 is actually available
  29. for the drive.
  30. Arguments:
  31. Int13UnitNumber - supplies the int13 drive number for the drive
  32. to be read from/written to.
  33. StartSector - supplies the absolute physical sector number. This is 0-based
  34. relative to all sectors on the drive.
  35. SectorCount - supplies the number of sectors to read/write.
  36. Buffer - receives data read from the disk or supplies data to be written.
  37. Write - supplies a flag indicating whether this is a write operation.
  38. If FALSE, then it's a read. Otherwise it's a write.
  39. Return Value:
  40. ARC status code indicating outcome.
  41. --*/
  42. {
  43. ARC_STATUS s;
  44. ULONG l,h;
  45. UCHAR Operation;
  46. //
  47. // Buffer must be under 1MB to be addressable in real mode.
  48. // The hardcoded 512 is wrong the CD-ROM case, but close enough.
  49. //
  50. if(((ULONG)Buffer + (SectorCount * 512)) > 0x100000) {
  51. return(EFAULT);
  52. }
  53. if(!SectorCount) {
  54. return(ESUCCESS);
  55. }
  56. l = (ULONG)StartSector;
  57. h = (ULONG)(StartSector >> 32);
  58. Operation = (UCHAR)(Write ? 0x43 : 0x42);
  59. //
  60. // Retry a couple of times if this fails.
  61. // We don't reset since this routine is only used on hard drives and
  62. // CD-ROMs, and we don't totally understand the effect of a disk reset
  63. // on ElTorito.
  64. //
  65. s = GET_EDDS_SECTOR(Int13UnitNumber,l,h,SectorCount,Buffer,Operation);
  66. if(s) {
  67. s = GET_EDDS_SECTOR(Int13UnitNumber,l,h,SectorCount,Buffer,Operation);
  68. if(s) {
  69. s = GET_EDDS_SECTOR(Int13UnitNumber,l,h,SectorCount,Buffer,Operation);
  70. }
  71. }
  72. return(s);
  73. }
  74. ARC_STATUS
  75. XferPhysicalDiskSectors(
  76. IN UCHAR Int13UnitNumber,
  77. IN ULONGLONG StartSector,
  78. IN UCHAR SectorCount,
  79. IN PUCHAR Buffer,
  80. IN UCHAR SectorsPerTrack,
  81. IN USHORT Heads,
  82. IN USHORT Cylinders,
  83. IN BOOLEAN AllowExtendedInt13,
  84. IN BOOLEAN Write
  85. )
  86. /*++
  87. Routine Description:
  88. Read or write disk sectors.
  89. Xfers sectors via int13. If the request starts on a cylinder
  90. larger than the number of cylinders reported by conventional int13, then
  91. extended int13 will be used if the drive supports it.
  92. It is assumed that the caller has ensured that the transfer buffer is
  93. under the 1MB line, that the sector run does not cross a 64K boundary,
  94. and that the sector run does not cross a track boundary. (The latter
  95. might not be strictly necessary, but the i/o will fail if the sector run
  96. starts inside the magic CHS boundary and ends past it since we won't
  97. switch to xint13 unless the start sector indicates that it is necessary.)
  98. Arguments:
  99. Int13UnitNumber - supplies the int13 drive number for the drive
  100. to be read from/written to.
  101. StartSector - supplies the absolute physical sector number. This is 0-based
  102. relative to all sectors on the drive.
  103. SectorCount - supplies the number of sectors to read/write.
  104. Buffer - receives data read from the disk or supplies data to be written.
  105. SectorsPerTrack - supplies sectors per track (1-63) from int13 function 8
  106. for the drive.
  107. Heads - supplies number of heads (1-255) from int13 function 8 for the drive.
  108. Cylinders - supplies number of cylinders (1-1023) from int13 function 8
  109. for the drive.
  110. AllowExtendedInt13 - if TRUE and the start cylinder for the i/o is
  111. greater than the cylinder count reported by conventional int13 for
  112. the drive, then extended int13 will be used to do the i/o operation.
  113. Write - supplies a flag indicating whether this is a write operation.
  114. If FALSE, then it's a read. Otherwise it's a write.
  115. Return Value:
  116. ARC status code indicating outcome.
  117. --*/
  118. {
  119. ULONGLONG r;
  120. ULONGLONG cylinder;
  121. USHORT head;
  122. UCHAR sector;
  123. USHORT SectorsPerCylinder;
  124. int retry;
  125. ARC_STATUS s;
  126. //
  127. // Buffer must be under 1MB to be addressable in real mode
  128. //
  129. if(((ULONG)Buffer + (SectorCount * 512)) > 0x100000) {
  130. return(EFAULT);
  131. }
  132. //
  133. // Figure out CHS values. Note that we use a ULONGLONG for the cylinder,
  134. // because it could overflow 1023 if the start sector is large.
  135. //
  136. SectorsPerCylinder = SectorsPerTrack * Heads;
  137. cylinder = (ULONG)(StartSector / SectorsPerCylinder);
  138. r = StartSector % SectorsPerCylinder;
  139. head = (USHORT)(r / SectorsPerTrack);
  140. sector = (UCHAR)(r % SectorsPerTrack) + 1;
  141. //
  142. // Check to see whether the cylinder is addressable via conventional int13.
  143. //
  144. if(cylinder >= Cylinders) {
  145. //
  146. // First try standard int13.
  147. // Some BIOSes (Thinkpad 600) misreport the disk size and ext int13.
  148. // So let's get this case out of the way now by trying the read anyway.
  149. //
  150. if( cylinder == Cylinders ) {
  151. if( cylinder <= 1023 ) {
  152. //
  153. // Give conventional int13 a shot.
  154. //
  155. s = GET_SECTOR(
  156. (UCHAR)(Write ? 3 : 2), // int13 function number
  157. Int13UnitNumber,
  158. head,
  159. (USHORT)cylinder, // we know it's 0-1023
  160. sector,
  161. SectorCount,
  162. Buffer
  163. );
  164. if(s) {
  165. //
  166. // failed, fall through to ExtendedInt13
  167. //
  168. } else {
  169. // success, let's return
  170. return(s);
  171. }
  172. }
  173. }
  174. if(AllowExtendedInt13) {
  175. s = XferExtendedPhysicalDiskSectors(
  176. Int13UnitNumber,
  177. StartSector,
  178. SectorCount,
  179. Buffer,
  180. Write
  181. );
  182. return(s);
  183. //
  184. // The read is beyond the geometry reported by the BIOS. If it's
  185. // in the first cylinder beyond that reported by the BIOS, and
  186. // it's below cylinder 1024, then assume that the BIOS and NT
  187. // just have a slight disagreement about the geometry and try
  188. // the read using conventional int13.
  189. //
  190. } else if((cylinder > 1023) || (cylinder > Cylinders)) {
  191. return(E2BIG);
  192. }
  193. //
  194. // The read is in the "extra" cylinder. Fall through to conventional int13.
  195. //
  196. }
  197. if(!SectorCount) {
  198. return(ESUCCESS);
  199. }
  200. //
  201. // OK, xfer the sectors via conventional int13.
  202. //
  203. retry = (Int13UnitNumber < 128) ? 3 : 1;
  204. do {
  205. s = GET_SECTOR(
  206. (UCHAR)(Write ? 3 : 2), // int13 function number
  207. Int13UnitNumber,
  208. head,
  209. (USHORT)cylinder, // we know it's 0-1023
  210. sector,
  211. SectorCount,
  212. Buffer
  213. );
  214. if(s) {
  215. ResetDiskSystem(Int13UnitNumber);
  216. }
  217. } while(s && retry--);
  218. return(s);
  219. }
  220. VOID
  221. ResetDiskSystem(
  222. UCHAR Int13UnitNumber
  223. )
  224. /*++
  225. Routine Description:
  226. Reset the specified drive. Generally used after an error is returned
  227. by the GetSector routine.
  228. Arguments:
  229. Int13UnitNumber -
  230. 0x00 - 1st floppy drive
  231. 0x01 - 2nd floppy drive
  232. 0x80 - 1st hard drive
  233. 0x81 - 2nd hard drive
  234. etc
  235. Returns:
  236. None.
  237. --*/
  238. {
  239. RESET_DISK(
  240. (UCHAR)((Int13UnitNumber < 128) ? 0 : 13), // int13 function number
  241. Int13UnitNumber,
  242. 0,
  243. 0,
  244. 0,
  245. 0,
  246. NULL
  247. );
  248. }
  249. VOID
  250. MdShutoffFloppy(
  251. VOID
  252. )
  253. /*++
  254. Routine Description:
  255. Shuts off the floppy drive motor.
  256. Arguments:
  257. None
  258. Return Value:
  259. None.
  260. --*/
  261. {
  262. WRITE_PORT_UCHAR(FLOPPY_CONTROL_REGISTER,0xC);
  263. }