#help_index "PCI;Info;File/System;Devices" public I64 SATARep(I64 bd_type=BDT_NULL) { // Report ATA and ATAPI drives implemented by SATA controller. I64 bdf, i, j, num = 0; CAHCIPort *port; CPCIDev *pci; CBlkDev *temp_blkdev; U16 *st, *model, *serial; Bool show_atapi = FALSE, show_ata = FALSE; switch (bd_type) { case BDT_NULL: show_atapi = show_ata = TRUE; break; case BDT_ATAPI: show_atapi = TRUE; break; case BDT_ATA: show_ata = TRUE; break; } if (!IsRaw) "\n$LTBLUE$AHCI version %X.%1X%1X$FG$\n\n", blkdev.ahci_hba->version >> 16, (blkdev.ahci_hba->version & 0xFF00) >> 8, blkdev.ahci_hba->version & 0xFF; else "\nAHCI version %X.%1X%1X\n\n", blkdev.ahci_hba->version >> 16, (blkdev.ahci_hba->version & 0xFF00) >> 8, blkdev.ahci_hba->version & 0xFF; if (dev.pci_head) { pci = PCIDevFind(PCIC_STORAGE, PCISC_AHCI); if (!IsRaw) { "$RED$$HL,1$Bus: 0x%02X, Dev: 0x%02X, Fun: 0x%02X$HL,0$$FG$\n\n", pci->bus, pci->dev, pci->fun; "$RED$Vendor$FG$: $LTBLUE$%s$FG$\n", pci->vendor_str; "$RED$Device$FG$: $LTBLUE$%s$FG$\n", pci->dev_id_str; } else { "Bus: 0x%02X, Dev: 0x%02X, Fun: 0x%02X\n\n", pci->bus, pci->dev, pci->fun; "Vendor: %s\n", pci->vendor_str; "Device: %s\n", pci->dev_id_str; } } else { bdf = PCIClassFind(PCIC_STORAGE << 16 | PCISC_AHCI << 8 + 1, 0); "Bus:%02X, Dev:%02X, Fun:%02X\n", bdf.u8[2], bdf.u8[1], bdf.u8[0]; "HBA Base Address: 0x%X", PCIReadU32(bdf.u8[2], bdf.u8[1], bdf.u8[0], PCIR_BASE5) & ~0x1F; } if (blkdev.ahci_hba) { "\nImplemented Ports:\n"; "(Show ATA: %Z)\n", show_ata, "ST_FALSE_TRUE"; "(Show ATAPI: %Z)\n\n", show_atapi, "ST_FALSE_TRUE"; for (i = 0; i < AHCI_MAX_PORTS; i++) { if (PCIBt(&blkdev.ahci_hba->ports_implemented, i)) { port = &blkdev.ahci_hba->ports[i]; if (port->signature == AHCI_PxSIG_ATAPI && show_atapi || port->signature == AHCI_PxSIG_ATA && show_ata) { if (!IsRaw) "$PURPLE$ $BT,\"%d\",LM=\"%d\n\"$$FG$", i, i; else "[%d]", i; if (port->signature == AHCI_PxSIG_ATA) { if (!IsRaw) "$LM,4$$RED$Hard Drive $LTBLUE$ATA$FG$\n"; else "\tHard Drive ATA\n"; } else if (port->signature == AHCI_PxSIG_ATAPI) { if (!IsRaw) "$LM,4$$RED$CD/DVD Drive $LTBLUE$ATAPI$FG$\n"; else "\tCD/DVD Drive ATAPI\n"; } if (!IsRaw) "$LM,0$"; '\n\t'; temp_blkdev = CAlloc(sizeof(CBlkDev)); if (port->signature == AHCI_PxSIG_ATAPI) temp_blkdev->first_drive_let = 'T'; else // ATA temp_blkdev->first_drive_let = 'C'; try AHCIPortInit(temp_blkdev, port, i); catch { Fs->catch_except = TRUE; "Error at SATA Port %d", i; } if (i == blkdev.ins_port) "\t(Drive originally installed from.)\n"; "\n\t"; if (temp_blkdev->dev_id_record) { st = CAlloc(40 + 1); for (j = 0; j < 20; j++) st[j] = EndianU16(temp_blkdev->dev_id_record[27 + j]); model = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING); "Model: %s\n\t", model; Free(st); Free(model); st = CAlloc(20 + 1); for (j = 0; j < 10; j++) st[j] = EndianU16(temp_blkdev->dev_id_record[10 + j]); serial = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING); "Serial: %s\n", serial; Free(st); Free(serial); } "\n"; BlkDevDel(temp_blkdev); Free(temp_blkdev); } num++; } } } else "blkdev.ahci_hba is NULL !\n\n"; return num; } #help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);" U8 Mount2(U8 boot_drive_let, CDoc *_doc, Bool _caller_is_prtdisk) {//If _doc, called by ::/Kernel/KConfig.ZC else called by Mount(). I64 count, total = 0, num_hints, drv_let, type, prt_num, port; U8 blks_buf[STR_LEN], addr_buf[STR_LEN], port_str[STR_LEN], *filename = NULL, *filename2 = NULL, res = 0; Bool whole_drive, make_free; CDoc *doc; if (boot_drive_let) boot_drive_let = Letter2Letter(boot_drive_let); do { count = 0; if (!_doc) DriveRep; if (!IsRaw) "\n****** Mount Drives ******\n" "$GREEN$A$FG$-$GREEN$B$FG$ are RAM drives.\n" "$GREEN$C$FG$-$GREEN$L$FG$ are ATA hard drives.\n" "$GREEN$M$FG$-$GREEN$P$FG$ are ISO file read drives.\n" "$GREEN$Q$FG$-$GREEN$S$FG$ are ISO file write drives.\n" "$GREEN$T$FG$-$GREEN$Z$FG$ are ATAPI CD/DVD drives.\n" "\nDrive Letter ($PURPLE$<ENTER>$FG$ to exit):"; else "\n****** Mount Drives ******\n" "A-B are RAM drives.\n" "C-L are ATA hard drives.\n" "M-P are ISO file read drives.\n" "Q-S are ISO file write drives.\n" "T-Z are ATAPI CD/DVD drives.\n" "\nDrive Letter (<ENTER> to exit):"; drv_let = Letter2Letter(CharGet); '\n'; if (type = Letter2BlkDevType(drv_let)) { whole_drive = FALSE; if (_doc) { //Called by ::/Kernel/KConfig.ZC doc = _doc; make_free = FALSE; } else { //Called by Mount() doc = DocNew; DocPrint(doc, "CBlkDev *bd;\n"); make_free = TRUE; } prt_num = I64_MIN; port = -1; switch (type) { case BDT_RAM: if (!IsRaw) "Addr of RAM disk ($PURPLE$<ENTER>$FG$ to MAlloc):"; else "Addr of RAM disk (<ENTER> to MAlloc):"; StrNGet(addr_buf, STR_LEN); case BDT_ISO_FILE_WRITE: "Blocks of 512 bytes:"; StrNGet(blks_buf, STR_LEN); break; case BDT_ISO_FILE_READ: filename = StrGet("File Name:"); break; case BDT_ATA: prt_num = I64Get("Partition Num (Default=All):", prt_num); case BDT_ATAPI: num_hints = SATARep(type); if (type == BDT_ATAPI && boot_drive_let) "<ENTER> to use booted CD/DVD\n"; //Only ::/Kernel/KConfig.ZC do { if (num_hints) "Enter port number: \n"; StrNGet(port_str, STR_LEN); } while ((type == BDT_ATAPI && AHCIPortSignatureGet(Str2I64(port_str)) != AHCI_PxSIG_ATAPI || type == BDT_ATA && AHCIPortSignatureGet(Str2I64(port_str)) != AHCI_PxSIG_ATA || type == BDT_ATA && !*port_str || 0 > Str2I64(port_str) || Str2I64(port_str) > num_hints - 1 ) && (type != BDT_ATAPI || !boot_drive_let)); port = Str2I64(port_str); break; } DocPrint(doc, "\"bd = BlkDevNextFreeSlot('%C', %d);\n\";\n", drv_let, type); DocPrint(doc, "bd = BlkDevNextFreeSlot(\'%C\', %d);\n", drv_let, type); if (port != -1 && *port_str) { DocPrint(doc, "\"AHCIPortInit(bd, &blkdev.ahci_hba->ports[%d], %d);\n\";\n", port, port); DocPrint(doc, "AHCIPortInit(bd, &blkdev.ahci_hba->ports[%d], %d);\n", port, port); } switch (type) { case BDT_RAM: if (!*addr_buf) StrCopy(addr_buf, "0"); DocPrint(doc, "bd->RAM_disk = %s;\n", addr_buf); case BDT_ISO_FILE_WRITE: if (!*blks_buf) StrCopy(blks_buf, "0"); DocPrint(doc, "bd->max_blk = (%s) - 1;\n", blks_buf); DocPrint(doc, "bd->drv_offset = 19 << 2 + (DVD_BLK_SIZE * 2 + DVD_BOOT_LOADER_SIZE) / BLK_SIZE;\n"); break; case BDT_ISO_FILE_READ: filename2 = FileNameAbs(filename); DocPrint(doc, "bd->file_disk_name = SysStrNew(\"%s\");\n", filename2); DocPrint(doc, "bd->drv_offset = 19 << 2 + (DVD_BLK_SIZE * 2 + DVD_BOOT_LOADER_SIZE) / BLK_SIZE;\n"); break; case BDT_ATAPI: if (!*port_str && _doc) { DocPrint(doc, "\"AHCIBootDVDProbeAll(bd);\n\";\n"); DocPrint(doc, "AHCIBootDVDProbeAll(bd);\n"); //Only ::/Kernel/KConfig.ZC if (drv_let == boot_drive_let) make_free = TRUE; } break; case BDT_ATA: if (_caller_is_prtdisk) { "\nReformat WHOLE drive!"; whole_drive = YorN; } break; } DocPrint(doc, "\"BlkDevAdd(bd, 0x%0X, %Z, %Z);\n\";\n", prt_num, whole_drive, "ST_FALSE_TRUE", make_free, "ST_FALSE_TRUE"); DocPrint(doc, "BlkDevAdd(bd, 0x%0X, %d, %d);\n", prt_num, whole_drive, make_free); if (_doc) //Called by ::/Kernel/KConfig.ZC count++; else { //Called by Mount() if ((count = ExeDoc(doc)) && whole_drive) { if (_caller_is_prtdisk) { res = drv_let; DiskPart(drv_let, 1.0); //First mount whole drive. } else DiskPart(drv_let); } DocDel(doc); } } total += count; } while (count && !_caller_is_prtdisk || !total && _doc); //At least 1 if Called by ::/Kernel/KConfig.ZC Free(filename); Free(filename2); return res; } public U8 Mount(Bool caller_is_prtdisk=FALSE) {//Mount drives. Called from DiskPart(Mount). return Mount2(0, NULL, caller_is_prtdisk); } public U0 Unmount(U8 drv_let=0) {//Unmount drive(s). BlkDevDel(Letter2BlkDev(drv_let)); } public U8 MountFile(U8 *filename) {//Mount ISO.C file. U8 *filename2 = ExtDefault(filename, "ISO.C"), *filename3 = FileNameAbs(filename2); CDrive *drive = DriveMakeFreeSlot(DriveNextFreeLet('M')); //First BDT_ISO_FILE_READ CBlkDev *bd = BlkDevNextFreeSlot(drive->drv_let, BDT_ISO_FILE_READ); bd->drv_offset = 19 << 2 + (DVD_BLK_SIZE * 2 + DVD_BOOT_LOADER_SIZE) / BLK_SIZE; bd->file_disk_name = SysStrNew(filename3); BlkDevAdd(bd,, TRUE, TRUE); Free(filename3); Free(filename2); return drive->drv_let; }