bmik/Src/DskAddDev.HC

238 lines
6.4 KiB
HolyC

U0 BlkDevLockFwdingSet(
CBlkDev *bd) { // If two blkdevs on same controller, use just one lock
CBlkDev *bd1;
I64 i;
switch (bd->type) {
case BDT_RAM:
break;
case BDT_ISO_FILE_READ:
case BDT_ISO_FILE_WRITE:
bd->lock_fwding = Let2BlkDev(*bd->file_dsk_name);
break;
case BDT_ATA:
case BDT_ATAPI:
for (i = 0; i < BLKDEVS_NUM; i++) {
bd1 = &blkdev.blkdevs[i];
if (bd1->bd_signature == BD_SIGNATURE_VAL && bd != bd1 &&
(bd1->type == BDT_ATAPI || bd1->type == BDT_ATA) &&
bd1->base0 == bd->base0) {
bd->lock_fwding = bd1;
break;
}
}
break;
}
}
I64 BlkDevAdd(
CBlkDev *bd, I64 prt_num = I64_MIN, Bool whole_drv,
Bool make_free) { // It will mount just one partition of prt_num>=0.
// When repartitioing whole drive, whole_drv=TRUE.
I64 i, j, ext_base, offset, res = 0, num = 0;
CDrv *dv;
CRedSeaBoot br;
CMasterBoot mbr;
bd->bd_signature = BD_SIGNATURE_VAL;
if (make_free)
dv = DrvMakeFreeSlot(bd->first_drv_let);
else
dv = DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let));
dv->bd = bd;
dv->drv_offset = bd->drv_offset;
dv->size = bd->max_blk + 1 - bd->drv_offset;
switch (bd->type) {
case BDT_RAM:
case BDT_ISO_FILE_READ:
case BDT_ISO_FILE_WRITE:
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
dv->fs_type = FSt_REDSEA;
// This is to force creation of a RAM
// drive during boot, so it is probably
// MAlloced to the same addr and can
// be assumed to be already formatted.
// If this line is removed, RAM Drives
// will be alloced on a just-in-time
// basis.
if (BlkDevInit(bd))
res++;
else
dv->dv_signature = 0;
break;
case BDT_ATA:
dv->dv_signature = DRV_SIGNATURE_VAL; // Temporarily validate
if (!BlkDevInit(bd))
dv->dv_signature = 0; // Revoke validation
else {
dv->dv_signature = 0; // Revoke validation
if (whole_drv) {
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
dv->fs_type = FSt_REDSEA;
dv->size = bd->max_blk + 1 - bd->drv_offset;
// The following read is a test read.
// if it hangs, the drive is not supported.
ATAReadBlks(bd, &mbr, 0, 1);
break;
}
offset = 0;
ext_base = INVALID_CLUS;
while (prt_num < 0 || num <= prt_num) {
ATAReadBlks(bd, &mbr, offset, 1);
if (mbr.signature != 0xAA55)
break;
j = -1;
for (i = 0; i < 4 && (prt_num < 0 || num <= prt_num); i++) {
if (mbr.p[i].type) {
if (make_free)
dv = DrvMakeFreeSlot(bd->first_drv_let + res);
else
dv = DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let + res));
dv->bd = bd;
dv->drv_offset = mbr.p[i].offset + offset;
dv->size = mbr.p[i].size;
switch (mbr.p[i].type) {
case MBR_PT_REDSEA:
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
dv->fs_type = FSt_REDSEA;
RedSeaInit(dv);
break;
case MBR_PT_FAT32a:
case MBR_PT_FAT32b:
case MBR_PT_FAT32c:
case MBR_PT_FAT32d:
case MBR_PT_FAT32e:
case MBR_PT_FAT32f:
ATAReadBlks(bd, &br, dv->drv_offset, 1);
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
if (br.signature == MBR_PT_REDSEA) {
dv->fs_type = FSt_REDSEA;
RedSeaInit(dv);
} else {
dv->fs_type = FSt_FAT32;
FAT32Init(dv);
}
break;
case MBR_PT_NTFS:
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
dv->fs_type = FSt_NTFS;
break;
case 5:
case 15:
j = i;
break;
default:
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
dv->fs_type = FSt_UNKNOWN;
}
num++;
}
}
if (Let2BlkDevType(bd->first_drv_let + res) != bd->type)
break;
if (j < 0)
break;
if (!mbr.p[j].offset)
break;
if (ext_base == INVALID_CLUS) {
offset = mbr.p[j].offset;
ext_base = offset;
} else
offset = mbr.p[j].offset + ext_base;
}
}
break;
case BDT_ATAPI:
dv->dv_signature = DRV_SIGNATURE_VAL;
dv->prt_num = num;
res++;
dv->fs_type = FSt_ISO9660; // Start with this
dv->size = 0;
break;
}
if (res)
BlkDevLockFwdingSet(bd);
else
BlkDevDel(bd);
return res;
}
Bool DrvEnable(
U8 drv_let,
Bool val) { // Can unmount or remount, but not mount the first time.
CDrv *dv;
if (dv = Let2Drv(drv_let, FALSE))
return !LBEqu(&dv->fs_type, FStf_DISABLE, !val);
else
return FALSE;
}
I64 SysGetI64() {
U8 st[STR_LEN];
GetS(st, STR_LEN, FALSE);
return Str2I64(st, 16);
}
Bool GetBaseUnit(CBlkDev *bd) {
I64 ch;
Bool probe;
#exe {
if (kernel_cfg->opts[CFG_DONT_PROBE])
StreamPrint("probe=FALSE;");
else
StreamPrint("probe=TRUE;");
};
if (!probe || !BootDVDProbeAll(bd)) {
"\nDon't worry. This is not a product\n"
"registration. TempleOS just needs the\n"
"I/O port numbers for the CD/DVD.\n"
"\nRetry the ports above or check Windows\n"
"system information under I/O ports for\n"
"'IDE', 'ATA' or 'SATA'.\n"
"In Linux, use 'lspci -v' for ports.\n"
"\n\nEnter 4-digit hex I/O Port number.\n"
"CD/DVD I/O Port Base0: 0x";
bd->base0 = SysGetI64;
bd->base1 = 0;
bd->unit = 0;
if (bd->base0) {
"\nUnit (0 or 1): ";
do
ch = GetChar(, FALSE);
while (!('0' <= ch <= '1'));
'' ch;
bd->unit = ch - '0';
blkdev.dvd_boot_is_good = BootDVDProbe(bd);
return TRUE;
} else {
blkdev.dvd_boot_is_good = FALSE;
return FALSE;
}
}
return FALSE;
}
U0 BlkDevsInitAll() {
CBlkDev *bd;
I64 i;
blkdev.blkdevs = CAlloc(sizeof(CBlkDev) * BLKDEVS_NUM);
blkdev.drvs = CAlloc(sizeof(CDrv) * DRVS_NUM);
for (i = 0; i < DRVS_NUM; i++)
blkdev.let_to_drv[i] = &blkdev.drvs[i];
#exe {
StreamPrint("MountIDEAuto;");
StreamPrint("#exe {Option(OPTf_WARN_PAREN,OFF);}");
StreamDoc(kernel_cfg->add_dev);
StreamPrint("#exe {Option(OPTf_WARN_PAREN,ON);}");
};
}