U0 ATARepEntry(I64 base0, I64 base1, I64 unit, U8 *message, CATARep **_head, I64 *num_hints) { I64 type; base0 &= -8; base1 &= -4; CATARep *tmpha; if (type = IDEATAProbe(base0,base1,unit)) { *num_hints += 1; "\n$PURPLE$ $BT+X,\"%d\",LM=\"%d\\n\"$$FG$$LM,4$", *num_hints, *num_hints; if (type == BDT_ATA) "$RED$Hard Drive $LTBLUE$ATA "; else "$RED$CD/DVD Drive $LTBLUE$ATAPI "; "%s$FG$\n", message; if (base0 == blkdev.ins_base0 && unit == blkdev.ins_unit) "$PURPLE$(Drive originally installed from.)$FG$\n"; "Base0:0x%04X Base1:0x%04X Unit:%d$LM,0$\n", base0, base1, unit; if (_head) { tmpha = CAlloc(sizeof(CATARep)); tmpha->next = *_head; *_head = tmpha; tmpha->num = *num_hints; tmpha->type = type; tmpha->base0 = base0; tmpha->base1 = base1; tmpha->unit = unit; } } } Bool ATARepExitAllApplications() { "\nWe're going to probe hardware.\n" "$RED$Exit all other applications.$FG$\n" "Press '$PURPLE$p$FG$' to probe or '$PURPLE$s$FG$' to skip.\n"; if (ToUpper(CharGet(, FALSE)) == 'S') return TRUE; else return FALSE; } public I64 ATARep(Bool prompt=TRUE, Bool just_ide=FALSE, CATARep **_head=NULL) {//Report possible ATA devices by probing. Hard disks and CD/DVDs. I64 d1, d2, i, j, k, count = 0, unlock_flags = 0, num_hints = 0; #assert BLKDEVS_NUM <= 64 if (_head) *_head = NULL; if (prompt && ATARepExitAllApplications) return 0; for (i = 0; i < BLKDEVS_NUM; i++) if (blkdev.blkdevs[i].bd_signature == BD_SIGNATURE_VAL) BEqual(&unlock_flags, i, BlkDevLock(&blkdev.blkdevs[i])); if (!just_ide) for (k = 0; k < 256; k++) { i = -1; while (TRUE) { j = PCIClassFind(0x010100 + k, ++i); if (j < 0) break; "\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n", k, j.u8[2], j.u8[1], j.u8[0]; count++; d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x10); d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x14); if (d1 & 1 && d2 & 1) { ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints); } else { d1=0x1F0; d2=0x3F6; ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints); } d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x18); d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x1C); if (d1&1 && d2&1) { ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints); } else { d1 = 0x170; d2 = 0x376; ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints); } } } if (!count) { d1 = 0x1F0; d2 = 0x3F6; ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints); d1 = 0x170; d2 = 0x376; ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints); ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints); } '\n\n'; for (i = 0; i < BLKDEVS_NUM; i++) if (Bt(&unlock_flags, i)) BlkDevUnlock(&blkdev.blkdevs[i]); return num_hints; } CATARep *ATARepFind(CATARep *haystack_head, I64 needle_num) { while (haystack_head) { if (haystack_head->num == needle_num) return haystack_head; haystack_head = haystack_head->next; } return NULL; } CATARep *ATAIDDrives(CATARep *head, CATARep **_ata_drive, CATARep **_atapi_drive) {//This is for when trying to sort-out main hard drives and CD/DVD drives. CATARep *res = NULL, *tmpha = head, *ata_drive = NULL, *atapi_drive = NULL; CBlkDev *bd; Bool was_silent = Silent, ins_found = FALSE; bd = Letter2BlkDev(':', FALSE); Silent(was_silent); while (tmpha) { if (!res && bd && bd->type == tmpha->type) { if (bd->type == BDT_ATAPI && bd->base0 == tmpha->base0 && bd->unit == tmpha->unit) res = atapi_drive = tmpha; else if (bd->type == BDT_ATA && bd->base0 == tmpha->base0 && bd->base1 == tmpha->base1 && bd->unit == tmpha->unit) res = ata_drive=tmpha; } if (!res || res->type != tmpha->type) { if (tmpha->type == BDT_ATA) { if (!ata_drive || tmpha->unit<ata_drive->unit || tmpha->unit == ata_drive->unit && tmpha->num < ata_drive->num) ata_drive = tmpha; } else if (tmpha->type == BDT_ATAPI) { if (!atapi_drive || !ins_found && (tmpha->unit < atapi_drive->unit || tmpha->unit == atapi_drive->unit && tmpha->num < atapi_drive->num)) atapi_drive = tmpha; } } if (tmpha->type == BDT_ATAPI && bd && bd->type == BDT_ATA && tmpha->base0 == blkdev.ins_base0 && tmpha->unit == blkdev.ins_unit) { if (!ins_found) { atapi_drive = tmpha; ins_found = TRUE; } } tmpha = tmpha->next; } if (_ata_drive) *_ata_drive = ata_drive; if (_atapi_drive) *_atapi_drive = atapi_drive; return res; } CBlkDev *ATAMount(U8 first_drive_let, I64 type, I64 base0, I64 base1, I64 unit) { CBlkDev *res; if (0 <= first_drive_let - 'A' < DRIVES_NUM && (type == BDT_ATA || type == BDT_ATAPI) && 0 <= unit <= 1) { res = BlkDevNextFreeSlot(first_drive_let, type); res->unit = unit; res->base0 = base0; res->base1 = base1; if (BlkDevAdd(res,, FALSE, FALSE)) return res; } return NULL; } I64 MountIDEAuto() {//Try to mount hard drive and CD/DVD, automatically. (Kernel.Config option). //It uses 'C' and 'T' as first drive letters or whatever you set //in config when compiling Kernel.BIN. I64 res = 0; CATARep *head = NULL, *ata_drive = NULL, *atapi_drive = NULL, *tmpha; ATARep(FALSE, TRUE, &head); ATAIDDrives(head, &ata_drive, &atapi_drive); if (ata_drive && ATAMount(blkdev.first_hd_drive_let, BDT_ATA, ata_drive->base0, ata_drive->base1, ata_drive->unit)) res++; if (atapi_drive && ATAMount(blkdev.first_dvd_drive_let, BDT_ATAPI, atapi_drive->base0, atapi_drive->base1, atapi_drive->unit)) res++; tmpha = head; while (tmpha) { if (tmpha != ata_drive && tmpha != atapi_drive) { if (tmpha->type == BDT_ATA && ATAMount(blkdev.first_hd_drive_let, BDT_ATA, tmpha->base0, tmpha->base1, tmpha->unit)) res++; else if (tmpha->type == BDT_ATAPI && ATAMount(blkdev.first_dvd_drive_let, BDT_ATAPI, tmpha->base0, tmpha->base1, tmpha->unit)) res++; } tmpha = tmpha->next; } LinkedListDel(head); blkdev.mount_ide_auto_count = res; return res; }