Source code of Windows XP (NT5)
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.

984 lines
26 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. diskc.c
  5. Abstract:
  6. This is the NEC PD756 (aka AT, aka ISA, aka ix86) and Intel 82077
  7. (aka MIPS) floppy diskette detection code for NT. This file also
  8. collect BIOS disk drive parameters.
  9. Author:
  10. Shie-Lin Tzong (shielint) Dec-26-1991.
  11. Environment:
  12. x86 real mode.
  13. Revision History:
  14. Notes:
  15. --*/
  16. //
  17. // Include files.
  18. //
  19. #include "hwdetect.h"
  20. #include "disk.h"
  21. #if defined(NEC_98)
  22. #include "string.h"
  23. #else // PC98
  24. #include <string.h>
  25. #endif // PC98
  26. FPFWCONFIGURATION_COMPONENT_DATA
  27. GetFloppyInformation(
  28. VOID
  29. )
  30. /*++
  31. Routine Description:
  32. This routine tries to get floppy configuration information.
  33. Arguments:
  34. None.
  35. Return Value:
  36. A pointer to a FPCONFIGURATION_COMPONENT_DATA is returned. It is
  37. the head of floppy component tree root.
  38. --*/
  39. {
  40. UCHAR DriveType;
  41. FPUCHAR ParameterTable;
  42. FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry = NULL;
  43. FPFWCONFIGURATION_COMPONENT_DATA FirstController = NULL;
  44. FPFWCONFIGURATION_COMPONENT Component;
  45. HWCONTROLLER_DATA ControlData;
  46. UCHAR FloppyNumber = 0;
  47. UCHAR DiskName[30];
  48. UCHAR FloppyParmTable[FLOPPY_PARAMETER_TABLE_LENGTH];
  49. FPUCHAR fpString;
  50. USHORT Length, z;
  51. ULONG MaxDensity = 0;
  52. CM_FLOPPY_DEVICE_DATA far *FloppyData;
  53. FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
  54. USHORT FloppyDataVersion;
  55. #if defined(NEC_98)
  56. USHORT DiskEquips;
  57. USHORT Disk2HC;
  58. UCHAR Counter = 0;
  59. BOOLEAN FdIoLocked = FALSE;
  60. UCHAR status;
  61. UCHAR driveExchange;
  62. DiskEquips = DISK_EQUIPS_FD;
  63. Disk2HC = DISK_2HC;
  64. if ( (COM_ID_L == 0x98) && (COM_ID_H == 0x21) &&
  65. (ROM_FLAG7 & LOCKED_FD) ){
  66. FdIoLocked = TRUE;
  67. }
  68. #endif // PC98
  69. for (z = 0; z < FLOPPY_PARAMETER_TABLE_LENGTH; z++ ) {
  70. FloppyParmTable[z] = 0;
  71. }
  72. //
  73. // Initialize Controller data
  74. //
  75. ControlData.NumberPortEntries = 0;
  76. ControlData.NumberIrqEntries = 0;
  77. ControlData.NumberMemoryEntries = 0;
  78. ControlData.NumberDmaEntries = 0;
  79. z = 0;
  80. //
  81. // Allocate space for Controller component and initialize it.
  82. //
  83. CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  84. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  85. FirstController = CurrentEntry;
  86. Component = &CurrentEntry->ComponentEntry;
  87. Component->Class = ControllerClass;
  88. Component->Type = DiskController;
  89. Component->Flags.Removable = 1;
  90. Component->Flags.Input = 1;
  91. Component->Flags.Output = 1;
  92. Component->Version = 0;
  93. Component->Key = 0;
  94. Component->AffinityMask = 0xffffffff;
  95. //
  96. // Set up Port information
  97. //
  98. ControlData.NumberPortEntries = 1;
  99. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  100. ControlData.DescriptorList[z].ShareDisposition =
  101. CmResourceShareDeviceExclusive;
  102. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  103. #if defined(NEC_98)
  104. ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)0x90;
  105. #else // PC98
  106. ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)0x3f0;
  107. #endif // PC98
  108. ControlData.DescriptorList[z].u.Port.Start.HighPart = (ULONG)0;
  109. ControlData.DescriptorList[z].u.Port.Length = 8;
  110. z++;
  111. //
  112. // Set up Irq information
  113. //
  114. ControlData.NumberIrqEntries = 1;
  115. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  116. ControlData.DescriptorList[z].ShareDisposition =
  117. CmResourceShareUndetermined;
  118. if (HwBusType == MACHINE_TYPE_MCA) {
  119. ControlData.DescriptorList[z].Flags = LEVEL_SENSITIVE;
  120. } else {
  121. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  122. }
  123. #if defined(NEC_98)
  124. ControlData.DescriptorList[z].u.Interrupt.Level = 11;
  125. ControlData.DescriptorList[z].u.Interrupt.Vector = 0x13;
  126. #else // PC98
  127. ControlData.DescriptorList[z].u.Interrupt.Level = 6;
  128. ControlData.DescriptorList[z].u.Interrupt.Vector = 6;
  129. #endif // PC98
  130. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  131. z++;
  132. //
  133. // Set up DMA information. Only set channel number. Timming and
  134. // transferSize are defaulted - 8 bits and ISA compatible.
  135. //
  136. ControlData.NumberDmaEntries = 1;
  137. ControlData.DescriptorList[z].Type = RESOURCE_DMA;
  138. ControlData.DescriptorList[z].ShareDisposition =
  139. CmResourceShareUndetermined;
  140. ControlData.DescriptorList[z].Flags = 0;
  141. ControlData.DescriptorList[z].u.Dma.Channel = (ULONG)2;
  142. ControlData.DescriptorList[z].u.Dma.Port = 0;
  143. z++;
  144. CurrentEntry->ConfigurationData =
  145. HwSetUpResourceDescriptor(Component,
  146. NULL,
  147. &ControlData,
  148. 0,
  149. NULL
  150. );
  151. #if _GAMBIT_
  152. //
  153. // Supply the DriveTypeValue that is supplied by the following IA
  154. // assembly programs.
  155. //
  156. DriveType = 0;
  157. FloppyDataVersion = 0;
  158. ParameterTable = NULL;
  159. //
  160. // Collect disk peripheral data
  161. //
  162. while (1) {
  163. #else
  164. #if defined(NEC_98)
  165. DriveType = 0;
  166. FloppyDataVersion = 0;
  167. driveExchange = 0;
  168. if ( DiskEquips & 0x0F ) {
  169. //
  170. // Check drive exchange.
  171. //
  172. status = READ_PORT_UCHAR((PUCHAR)0x94) & 0x04;
  173. if ( status == 0 ) {
  174. //
  175. // internal drive is #3/#4.
  176. //
  177. driveExchange = 1;
  178. }
  179. }
  180. if ( !(FdIoLocked) && Counter < 4 ){
  181. if ( DiskEquips & (1 << Counter ) ){
  182. //
  183. // Check internal drive or extension drive.
  184. //
  185. if ( (Counter / (UCHAR)2) == driveExchange ) {
  186. if (Disk2HC & (1 << Counter)) {
  187. //
  188. // 1.44MB drive
  189. //
  190. DriveType = 4;
  191. } else {
  192. //
  193. // 1.2MB drive
  194. //
  195. DriveType = 2;
  196. }
  197. } else {
  198. //
  199. // 1.2MB extension drive.
  200. //
  201. DriveType = 7;
  202. }
  203. Counter++;
  204. } else {
  205. Counter++;
  206. continue;
  207. }
  208. }
  209. #else // PC98
  210. _asm {
  211. push es
  212. mov DriveType, 0
  213. mov FloppyDataVersion, CURRENT_FLOPPY_DATA_VERSION
  214. mov ah, 15h
  215. mov dl, FloppyNumber
  216. int 13h
  217. jc short CmosTest
  218. cmp ah, 0
  219. je short Exit
  220. cmp ah, 2 ; make sure this is floppy
  221. ja short Exit
  222. mov ah, 8
  223. mov dl, FloppyNumber
  224. lea di, word ptr FloppyParmTable ; use 'word ptr' to quiet compiler
  225. push ds
  226. pop es ; (es:di)->dummy FloppyParmTable
  227. int 13h
  228. jc short CmosTest
  229. mov DriveType, bl
  230. mov ax, es
  231. mov word ptr ParameterTable + 2, ax
  232. mov word ptr ParameterTable, di
  233. jmp short Exit
  234. CmosTest:
  235. ;
  236. ; if int 13 fails, we know that floppy drive is present.
  237. ; So, we try to get the Drive Type from CMOS.
  238. ;
  239. mov al, CMOS_FLOPPY_CONFIG_BYTE
  240. mov dx, CMOS_CONTROL_PORT ; address port
  241. out dx, al
  242. jmp $ + 2 ; I/O DELAY
  243. mov dx, CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
  244. in al, dx
  245. jmp $ + 2 ; I/O DELAY
  246. cmp FloppyNumber, 0
  247. jne short CmosTest1
  248. and al, 0xf0
  249. shr al, 4
  250. jmp short CmosTest2
  251. CmosTest1:
  252. cmp FloppyNumber, 1
  253. jne short Exit
  254. and al, 0xf
  255. CmosTest2:
  256. mov DriveType, al
  257. mov FloppyDataVersion, 0
  258. Exit:
  259. pop es
  260. }
  261. #endif // PC98
  262. #endif // _GAMBIT_
  263. if (DriveType) {
  264. //
  265. // Allocate space for first pripheral component and initialize it.
  266. //
  267. CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  268. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  269. Component = &CurrentEntry->ComponentEntry;
  270. Component->Class = PeripheralClass;
  271. Component->Type = FloppyDiskPeripheral;
  272. Component->Version = 0;
  273. Component->Key = FloppyNumber;
  274. Component->AffinityMask = 0xffffffff;
  275. Component->ConfigurationDataLength = 0;
  276. //
  277. // Set up type string.
  278. //
  279. strcpy(DiskName, "FLOPPYx");
  280. DiskName[6] = FloppyNumber + (UCHAR)'1';
  281. Length = strlen(DiskName) + 1;
  282. fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
  283. _fstrcpy(fpString, DiskName);
  284. Component->IdentifierLength = Length;
  285. Component->Identifier = fpString;
  286. //
  287. // Set up floppy device specific data
  288. //
  289. switch (DriveType) {
  290. case 1:
  291. MaxDensity = 360;
  292. break;
  293. case 2:
  294. MaxDensity = 1200;
  295. break;
  296. case 3:
  297. MaxDensity = 720;
  298. break;
  299. case 4:
  300. MaxDensity = 1440;
  301. break;
  302. case 5:
  303. case 6:
  304. MaxDensity = 2880;
  305. break;
  306. #if defined(NEC_98)
  307. case 7:
  308. MaxDensity = 1201;
  309. break;
  310. #endif
  311. default:
  312. MaxDensity = 0;
  313. break;
  314. }
  315. if (FloppyDataVersion == CURRENT_FLOPPY_DATA_VERSION) {
  316. Length = sizeof(CM_FLOPPY_DEVICE_DATA);
  317. } else {
  318. Length = (SHORT)&(((CM_FLOPPY_DEVICE_DATA*)0)->StepRateHeadUnloadTime);
  319. }
  320. DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(
  321. Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST),
  322. TRUE);
  323. CurrentEntry->ConfigurationData = DescriptorList;
  324. Component->ConfigurationDataLength =
  325. Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST);
  326. DescriptorList->Count = 1;
  327. DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  328. DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
  329. Length;
  330. FloppyData = (CM_FLOPPY_DEVICE_DATA far *)(DescriptorList + 1);
  331. FloppyData->MaxDensity = MaxDensity;
  332. FloppyData->Version = FloppyDataVersion;
  333. if (FloppyDataVersion == CURRENT_FLOPPY_DATA_VERSION) {
  334. _fmemcpy((FPCHAR)&FloppyData->StepRateHeadUnloadTime,
  335. ParameterTable,
  336. sizeof(CM_FLOPPY_DEVICE_DATA) -
  337. (SHORT)&(((CM_FLOPPY_DEVICE_DATA*)0)->StepRateHeadUnloadTime)
  338. );
  339. }
  340. if (FloppyNumber == 0) {
  341. FirstController->Child = CurrentEntry;
  342. } else {
  343. PreviousEntry->Sibling = CurrentEntry;
  344. }
  345. CurrentEntry->Parent = FirstController;
  346. PreviousEntry = CurrentEntry;
  347. FloppyNumber++;
  348. } else {
  349. //
  350. // This is a *hack* for ntldr. Here we create a arc name for
  351. // each bios disks such that ntldr can open them.
  352. //
  353. if (NumberBiosDisks != 0) {
  354. for (z = 0; z < NumberBiosDisks; z++) {
  355. //
  356. // Allocate space for disk peripheral component
  357. //
  358. CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  359. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  360. Component = &CurrentEntry->ComponentEntry;
  361. Component->Class = PeripheralClass;
  362. Component->Type = DiskPeripheral;
  363. Component->Flags.Input = 1;
  364. Component->Flags.Output = 1;
  365. Component->Version = 0;
  366. Component->Key = z;
  367. Component->AffinityMask = 0xffffffff;
  368. //
  369. // Set up identifier string = 8 digit signature - 8 digit checksum
  370. // for example: 00fe964d-005467dd
  371. //
  372. GetDiskId((USHORT)(0x80 + z), DiskName);
  373. if (DiskName[0] == (UCHAR)NULL) {
  374. strcpy(DiskName, "BIOSDISKx");
  375. DiskName[8] = (UCHAR)z + (UCHAR)'1';
  376. }
  377. Length = strlen(DiskName) + 1;
  378. fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
  379. _fstrcpy(fpString, DiskName);
  380. Component->IdentifierLength = Length;
  381. Component->Identifier = fpString;
  382. #if defined(NEC_98)
  383. #else // PC98
  384. #if !defined(_GAMBIT_)
  385. //
  386. // Set up BIOS disk device specific data.
  387. // (If extended int 13 drive parameters are supported by
  388. // BIOS, we will collect them and store them here.)
  389. //
  390. if (IsExtendedInt13Available(0x80+z)) {
  391. DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(
  392. sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
  393. sizeof(CM_DISK_GEOMETRY_DEVICE_DATA),
  394. TRUE);
  395. Length = GetExtendedDriveParameters(
  396. 0x80 + z,
  397. (CM_DISK_GEOMETRY_DEVICE_DATA far *)(DescriptorList + 1)
  398. );
  399. if (Length) {
  400. CurrentEntry->ConfigurationData = DescriptorList;
  401. Component->ConfigurationDataLength =
  402. Length + sizeof(HWRESOURCE_DESCRIPTOR_LIST);
  403. DescriptorList->Count = 1;
  404. DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  405. DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
  406. Length;
  407. } else {
  408. HwFreeHeap(sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
  409. sizeof(CM_DISK_GEOMETRY_DEVICE_DATA));
  410. }
  411. }
  412. #endif // _GAMBIT_
  413. #endif // PC98
  414. if (PreviousEntry == NULL) {
  415. FirstController->Child = CurrentEntry;
  416. } else {
  417. PreviousEntry->Sibling = CurrentEntry;
  418. }
  419. CurrentEntry->Parent = FirstController;
  420. PreviousEntry = CurrentEntry;
  421. }
  422. }
  423. return(FirstController);
  424. }
  425. }
  426. }
  427. VOID
  428. GetDiskId(
  429. USHORT Disk,
  430. PUCHAR Identifier
  431. )
  432. /*++
  433. Routine Description:
  434. This routine reads the master boot sector of the specified harddisk drive,
  435. compute the checksum of the sector to form a drive identifier.
  436. The identifier will be set to "8-digit-checksum"+"-"+"8-digit-signature"
  437. For example: 00ff6396-6549071f
  438. Arguments:
  439. Disk - supplies the BIOS drive number, i.e. 80h - 87h
  440. Identifier - Supplies a buffer to receive the disk id.
  441. Return Value:
  442. None. In the worst case, the Identifier will be empty.
  443. --*/
  444. {
  445. #if defined(_GAMBIT_)
  446. Identifier = NULL;
  447. #else
  448. #if defined(NEC_98)
  449. USHORT BootRecordSignature; // Boot Record Signature (0x55aa)
  450. UCHAR diskNumber;
  451. UCHAR Sector[1024];
  452. #else // PC98
  453. UCHAR Sector[512];
  454. #endif // PC98
  455. ULONG Signature, Checksum;
  456. USHORT i, Length;
  457. PUCHAR BufferAddress;
  458. BOOLEAN Fail;
  459. Identifier[0] = 0;
  460. BufferAddress = &Sector[0];
  461. Fail = FALSE;
  462. //
  463. // Read in the first sector
  464. //
  465. #if defined(NEC_98)
  466. //
  467. // We can't access over 4GB except relative access.
  468. // Therefore we use a relative(Sequential) access.
  469. //
  470. Disk &= 0x7F;
  471. diskNumber = (UCHAR)Disk;
  472. //
  473. // Read sectors (NTFS Signature)
  474. //
  475. _asm {
  476. push es
  477. mov ah, 0x06 // Disk read command
  478. mov al, diskNumber // Disk No (00,01)
  479. mov bx, 512 // Data length
  480. mov cx, 0x10 // Sector LSW
  481. mov dx, 0x00 // Sector HSW
  482. push ss
  483. pop es
  484. push bp
  485. mov bp, BufferAddress // ES:BP Buffer address
  486. int 0x1b
  487. pop bp
  488. pop es
  489. jnc Gdi000
  490. mov Fail, 1
  491. Gdi000:
  492. }
  493. #else // PC98
  494. _asm {
  495. push es
  496. mov ax, 0x201
  497. mov cx, 1
  498. mov dx, Disk
  499. push ss
  500. pop es
  501. mov bx, BufferAddress
  502. int 0x13
  503. pop es
  504. jnc Gdixxx
  505. mov Fail, 1
  506. Gdixxx:
  507. }
  508. #endif // PC98
  509. if (Fail) {
  510. #if DBG
  511. // could not get the sector, so return NULL DiskID
  512. BlPrint("Failed to read sector -- returning NULL DiskId\n");
  513. #endif
  514. return;
  515. }
  516. #if defined(NEC_98)
  517. //
  518. // Get the NTFS Sinature
  519. //
  520. if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
  521. Signature = 0;
  522. } else {
  523. Signature = ((PULONG)Sector)[0];
  524. }
  525. #else // PC98
  526. Signature = ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1];
  527. #endif // PC98
  528. //
  529. // compute the checksum
  530. //
  531. #if defined(NEC_98)
  532. //
  533. // Read No 0 and 1 sectors. (for Check Sum)
  534. //
  535. _asm {
  536. push es
  537. mov ah, 0x06 // Disk read command
  538. mov al, diskNumber // Disk No (00,01)
  539. mov bx, 512 * 2 // Data length
  540. mov cx, 0x00 // Sector LSW
  541. mov dx, 0x00 // Sector HSW
  542. push ss
  543. pop es
  544. push bp
  545. mov bp, BufferAddress // ES:BP Buffer address
  546. int 1bh
  547. pop bp
  548. pop es
  549. jnc Gdi001
  550. mov Fail, 1
  551. Gdi001:
  552. }
  553. if (Fail) {
  554. return;
  555. }
  556. #endif // PC98
  557. Checksum = 0;
  558. for (i = 0; i < 128; i++) {
  559. #if defined(NEC_98)
  560. Checksum += ((PULONG)Sector)[ i + 512/4 ];
  561. #else // PC98
  562. Checksum += ((PULONG)Sector)[i];
  563. #endif // PC98
  564. }
  565. Checksum = -Checksum;
  566. //
  567. // Zero the identifier
  568. //
  569. for (i=0; i < 30; i++) {
  570. Identifier[i]='0';
  571. }
  572. //
  573. // Put the dashes in the right places.
  574. //
  575. Identifier[8] = '-';
  576. Identifier[17] = '-';
  577. //
  578. // If the boot sector has a valid partition table signature,
  579. // attach an 'A.' Otherwise we use 'X.'
  580. //
  581. if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
  582. Identifier[18]='X';
  583. } else {
  584. Identifier[18]='A';
  585. }
  586. //
  587. // Reuse sector buffer to build checksum string.
  588. //
  589. ultoa(Checksum, Sector, 16);
  590. Length = strlen(Sector);
  591. for (i=0; i<Length; i++) {
  592. Identifier[7-i] = Sector[Length-i-1];
  593. }
  594. //
  595. // Reuse sector buffer to build signature string.
  596. //
  597. ultoa(Signature, Sector, 16);
  598. Length = strlen(Sector);
  599. for (i=0; i<Length; i++) {
  600. Identifier[16-i] = Sector[Length-i-1];
  601. }
  602. //
  603. // Terminate string.
  604. //
  605. Identifier[19] = 0;
  606. #if DBG
  607. BlPrint("%s\n", Identifier);
  608. #endif
  609. #endif // _GAMBIT_
  610. }
  611. #if defined(NEC_98)
  612. //
  613. // This section was used to get some SCSI disks' information connecting to
  614. // SCSI board that is includeing boot up disk.
  615. //
  616. // These information was very important when do FD-less setup.
  617. //
  618. // When the HIPER SCSI BIOS for array disk is abailable, it is useing a
  619. // trick to show two scsi board as one scsi board accessing through BIOS
  620. // functions.
  621. //
  622. // We must separete information per board from the two boards' information.
  623. //
  624. BOOLEAN
  625. BootedFromScsiDisk(
  626. PUSHORT pFakeScsiId,
  627. PUSHORT pNumberScsiDisks,
  628. PUSHORT pScsiDisksMap
  629. )
  630. {
  631. USHORT DauaBootedFrom;
  632. USHORT StartPosition = 0;
  633. USHORT EndPosition = SCSI_MAX_ID;
  634. USHORT tmp, i;
  635. DauaBootedFrom = DAUA_BOOTED_FROM;
  636. *pFakeScsiId = 0;
  637. *pNumberScsiDisks = 0;
  638. *pScsiDisksMap = DISK_EQUIPS_SCSI;
  639. if (!(DauaBootedFrom & DASCSI)){
  640. return (FALSE);
  641. }
  642. if ((EQUIPS_47Ch == (USHORT)0) && ((*pScsiDisksMap & 0x80) == 0)) {
  643. //
  644. // Array SCSI BIOS was available.
  645. //
  646. if (H_DISK_EQUIPS_L != (USHORT)0){ // we do not need high byte.
  647. tmp = H_EQUIPS;
  648. for ( i = 0; i < SCSI_MAX_ID; i++ ){
  649. if ( tmp & (1 << i)) (*pFakeScsiId)++;
  650. }
  651. if ( (DauaBootedFrom & UA_MASK) >= *pFakeScsiId ){
  652. //
  653. // System was booted from disk connected array scsi card.
  654. //
  655. StartPosition = *pFakeScsiId;
  656. EndPosition = SCSI_MAX_ID;
  657. } else {
  658. //
  659. // System was booted from disk connected normal scsi card.
  660. //
  661. StartPosition = 0;
  662. EndPosition = *pFakeScsiId;
  663. *pFakeScsiId = 0; // Reset
  664. }
  665. }
  666. }
  667. for ( i = StartPosition; i < EndPosition; i++ ){
  668. if ( *pScsiDisksMap & (1 << i)) (*pNumberScsiDisks)++;
  669. }
  670. *pFakeScsiId |= 0xA0;
  671. return(TRUE);
  672. }
  673. FPFWCONFIGURATION_COMPONENT_DATA
  674. GetScsiDiskInformation(
  675. VOID
  676. )
  677. /*++
  678. Routine Description:
  679. This routine tries to get SCSI Disk configuration information.
  680. Arguments:
  681. None.
  682. Return Value:
  683. A pointer to a FPCONFIGURATION_COMPONENT_DATA is returned. It is
  684. the head of floppy component tree root.
  685. --*/
  686. {
  687. FPFWCONFIGURATION_COMPONENT_DATA ControllerEntry, PreviousEntry = NULL;
  688. FPFWCONFIGURATION_COMPONENT_DATA PeripheralEntry;
  689. FPFWCONFIGURATION_COMPONENT_DATA FirstController = NULL;
  690. FPFWCONFIGURATION_COMPONENT_DATA AdapterEntry;
  691. FPFWCONFIGURATION_COMPONENT Component;
  692. CHAR Identifier[256];
  693. UCHAR DiskName[30];
  694. FPUCHAR fpString;
  695. USHORT Length;
  696. FPCHAR IdentifierString;
  697. USHORT DiskCount, Id;
  698. USHORT FakeScsiId;
  699. USHORT NumberScsiDisks;
  700. USHORT ScsiDisksMap;
  701. if (!BootedFromScsiDisk( &FakeScsiId, &NumberScsiDisks, &ScsiDisksMap )){
  702. return (NULL);
  703. }
  704. //
  705. // Allocate space for Controller component and initialize it.
  706. //
  707. AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  708. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  709. FirstController = AdapterEntry;
  710. Component = &AdapterEntry->ComponentEntry;
  711. Component->Class = AdapterClass;
  712. Component->Type = ScsiAdapter;
  713. strcpy (Identifier, "SCSI");
  714. Length = strlen(Identifier) + 1;
  715. IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
  716. _fstrcpy(IdentifierString, Identifier);
  717. Component->Version = 0;
  718. Component->Key = 0;
  719. Component->AffinityMask = 0xffffffff;
  720. Component->IdentifierLength = Length;
  721. Component->Identifier = IdentifierString;
  722. AdapterEntry->ConfigurationData = NULL;
  723. Component->ConfigurationDataLength = 0;
  724. for ( DiskCount = 0, Id = 0; DiskCount < NumberScsiDisks && Id < 7 ; Id++ ) {
  725. if ( !(ScsiDisksMap & (1 << (FakeScsiId + Id)))){
  726. continue;
  727. }
  728. //
  729. // Allocate space for disk peripheral component
  730. //
  731. ControllerEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  732. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  733. Component = &ControllerEntry->ComponentEntry;
  734. Component->Class = ControllerClass;
  735. Component->Type = DiskController;
  736. Component->Flags.Input = 1;
  737. Component->Flags.Output = 1;
  738. Component->Version = 0;
  739. Component->Key = Id;
  740. Component->AffinityMask = 0xffffffff;
  741. ControllerEntry->ConfigurationData = NULL;
  742. //
  743. // Set up identifier string = 8 digit signature - 8 digit checksum
  744. // for example: 00fe964d-005467dd
  745. //
  746. GetDiskId(FakeScsiId + Id, DiskName);
  747. if (DiskName[0] == (UCHAR)NULL) {
  748. strcpy(DiskName, "BIOSDISKx");
  749. DiskName[8] = (UCHAR)DiskCount + (UCHAR)'1';
  750. }
  751. Length = strlen(DiskName) + 1;
  752. fpString = (FPUCHAR)HwAllocateHeap(Length, FALSE);
  753. _fstrcpy(fpString, DiskName);
  754. Component->IdentifierLength = Length;
  755. Component->Identifier = fpString;
  756. //
  757. // Create Peripheral Entry
  758. //
  759. PeripheralEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  760. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  761. Component = &PeripheralEntry->ComponentEntry;
  762. Component->Class = PeripheralClass;
  763. Component->Type = DiskPeripheral;
  764. Component->Flags.Input = 1;
  765. Component->Flags.Output = 1;
  766. Component->Version = 0;
  767. Component->Key = 0;
  768. Component->AffinityMask = 0xffffffff;
  769. PeripheralEntry->ConfigurationData = NULL;
  770. Component->IdentifierLength = Length;
  771. Component->Identifier = fpString;
  772. PeripheralEntry->Parent = ControllerEntry;
  773. ControllerEntry->Child = PeripheralEntry;
  774. if (PreviousEntry == NULL) {
  775. FirstController->Child = ControllerEntry;
  776. } else {
  777. PreviousEntry->Sibling = ControllerEntry;
  778. }
  779. ControllerEntry->Parent = FirstController;
  780. PreviousEntry = ControllerEntry;
  781. DiskCount++;
  782. }
  783. return(FirstController);
  784. }
  785. #endif // PC98