// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 1996-2000 Russell King. * * Scan ADFS partitions on hard disk drives. Unfortunately, there * isn't a standard for partitioning drives on Acorn machines, so * every single manufacturer of SCSI and IDE cards created their own * method.
*/ #include <linux/buffer_head.h> #include <linux/adfs_fs.h>
#ifdef CONFIG_ACORN_PARTITION_CUMANA int adfspart_check_CUMANA(struct parsed_partitions *state)
{ unsignedlong first_sector = 0; unsignedint start_blk = 0;
Sector sect; unsignedchar *data; char *name = "CUMANA/ADFS"; int first = 1; int slot = 1;
/* * Try Cumana style partitions - sector 6 contains ADFS boot block * with pointer to next 'drive'. * * There are unknowns in this code - is the 'cylinder number' of the * next partition relative to the start of this one - I'm assuming * it is. * * Also, which ID did Cumana use? * * This is totally unfinished, and will require more work to get it * going. Hence it is totally untested.
*/ do { struct adfs_discrecord *dr; unsignedint nr_sects;
data = read_part_sector(state, start_blk * 2 + 6, §); if (!data) return -1;
if (slot == state->limit) break;
dr = adfs_partition(state, name, data, first_sector, slot++); if (!dr) break;
first = 0;
first_sector += nr_sects;
start_blk += nr_sects >> (BLOCK_SIZE_BITS - 9);
nr_sects = 0; /* hmm - should be partition size */
switch (data[0x1fc] & 15) { case 0: /* No partition / ADFS? */ break;
#ifdef CONFIG_ACORN_PARTITION_RISCIX case PARTITION_RISCIX_SCSI: /* RISCiX - we don't know how to find the next one. */
slot = riscix_partition(state, first_sector, slot,
nr_sects); break; #endif
case PARTITION_LINUX:
slot = linux_partition(state, first_sector, slot,
nr_sects); break;
}
put_dev_sector(sect); if (slot == -1) return -1;
} while (1);
put_dev_sector(sect); return first ? 0 : 1;
} #endif
#ifdef CONFIG_ACORN_PARTITION_ADFS /* * Purpose: allocate ADFS partitions. * * Params : hd - pointer to gendisk structure to store partition info. * dev - device number to access. * * Returns: -1 on error, 0 for no ADFS boot sector, 1 for ok. * * Alloc : hda = whole drive * hda1 = ADFS partition on first drive. * hda2 = non-ADFS partition.
*/ int adfspart_check_ADFS(struct parsed_partitions *state)
{ unsignedlong start_sect, nr_sects, sectscyl, heads;
Sector sect; unsignedchar *data; struct adfs_discrecord *dr; unsignedchar id; int slot = 1;
data = read_part_sector(state, 6, §); if (!data) return -1;
dr = adfs_partition(state, "ADFS", data, 0, slot++); if (!dr) {
put_dev_sector(sect); return 0;
}
staticint adfspart_check_ICSLinux(struct parsed_partitions *state, unsignedlong block)
{
Sector sect; unsignedchar *data = read_part_sector(state, block, §); int result = 0;
if (data) { if (memcmp(data, "LinuxPart", 9) == 0)
result = 1;
put_dev_sector(sect);
}
return result;
}
/* * Check for a valid ICS partition using the checksum.
*/ staticinlineint valid_ics_sector(constunsignedchar *data)
{ unsignedlong sum; int i;
for (i = 0, sum = 0x50617274; i < 508; i++)
sum += data[i];
sum -= le32_to_cpu(*(__le32 *)(&data[508]));
return sum == 0;
}
/* * Purpose: allocate ICS partitions. * Params : hd - pointer to gendisk structure to store partition info. * dev - device number to access. * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok. * Alloc : hda = whole drive * hda1 = ADFS partition 0 on first drive. * hda2 = ADFS partition 1 on first drive. * ..etc..
*/ int adfspart_check_ICS(struct parsed_partitions *state)
{ constunsignedchar *data; conststruct ics_part *p; int slot;
Sector sect;
/* * Negative sizes tell the RISC OS ICS driver to ignore * this partition - in effect it says that this does not * contain an ADFS filesystem.
*/ if (size < 0) {
size = -size;
/* * Our own extension - We use the first sector * of the partition to identify what type this * partition is. We must not make this visible * to the filesystem.
*/ if (size > 1 && adfspart_check_ICSLinux(state, start)) {
start += 1;
size -= 1;
}
}
if (size)
put_partition(state, slot++, start, size);
}
staticinlineint valid_ptec_sector(constunsignedchar *data)
{ unsignedchar checksum = 0x2a; int i;
/* * If it looks like a PC/BIOS partition, then it * probably isn't PowerTec.
*/ if (data[510] == 0x55 && data[511] == 0xaa) return 0;
for (i = 0; i < 511; i++)
checksum += data[i];
return checksum == data[511];
}
/* * Purpose: allocate ICS partitions. * Params : hd - pointer to gendisk structure to store partition info. * dev - device number to access. * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok. * Alloc : hda = whole drive * hda1 = ADFS partition 0 on first drive. * hda2 = ADFS partition 1 on first drive. * ..etc..
*/ int adfspart_check_POWERTEC(struct parsed_partitions *state)
{
Sector sect; constunsignedchar *data; conststruct ptec_part *p; int slot = 1; int i;
data = read_part_sector(state, 0, §); if (!data) return -1;
if (!valid_ptec_sector(data)) {
put_dev_sector(sect); return 0;
}
strlcat(state->pp_buf, " [POWERTEC]", PAGE_SIZE);
for (i = 0, p = (conststruct ptec_part *)data; i < 12; i++, p++) {
u32 start = le32_to_cpu(p->start);
u32 size = le32_to_cpu(p->size);
if (size)
put_partition(state, slot++, start, size);
}
/* * EESOX SCSI partition format. * * This is a goddamned awful partition format. We don't seem to store * the size of the partition in this table, only the start addresses. * * There are two possibilities where the size comes from: * 1. The individual ADFS boot block entries that are placed on the disk. * 2. The start address of the next entry.
*/ int adfspart_check_EESOX(struct parsed_partitions *state)
{
Sector sect; constunsignedchar *data; unsignedchar buffer[256]; struct eesox_part *p;
sector_t start = 0; int i, slot = 1;
data = read_part_sector(state, 7, §); if (!data) return -1;
/* * "Decrypt" the partition table. God knows why...
*/ for (i = 0; i < 256; i++)
buffer[i] = data[i] ^ eesox_name[i & 15];
put_dev_sector(sect);
for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) {
sector_t next;
if (memcmp(p->magic, "Eesox", 6)) break;
next = le32_to_cpu(p->start); if (i)
put_partition(state, slot++, start, next - start);
start = next;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.