// 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>

#include "check.h"
#include "acorn.h"

/*
 * Partition types. (Oh for reusability)
 */
#define PARTITION_RISCIX_MFM	1
#define PARTITION_RISCIX_SCSI	2
#define PARTITION_LINUX		9

#if defined(CONFIG_ACORN_PARTITION_CUMANA) || \
	defined(CONFIG_ACORN_PARTITION_ADFS)
static struct adfs_discrecord *
adfs_partition(struct parsed_partitions *state, char *name, char *data,
	       unsigned long first_sector, int slot)
{
	struct adfs_discrecord *dr;
	unsigned int nr_sects;

	if (adfs_checkbblk(data))
		return NULL;

	dr = (struct adfs_discrecord *)(data + 0x1c0);

	if (dr->disc_size == 0 && dr->disc_size_high == 0)
		return NULL;

	nr_sects = (le32_to_cpu(dr->disc_size_high) << 23) |
		   (le32_to_cpu(dr->disc_size) >> 9);

	if (name) {
		strlcat(state->pp_buf, " [", PAGE_SIZE);
		strlcat(state->pp_buf, name, PAGE_SIZE);
		strlcat(state->pp_buf, "]", PAGE_SIZE);
	}
	put_partition(state, slot, first_sector, nr_sects);
	return dr;
}
#endif

#ifdef CONFIG_ACORN_PARTITION_RISCIX

struct riscix_part {
	__le32	start;
	__le32	length;
	__le32	one;
	char	name[16];
};

struct riscix_record {
	__le32	magic;
#define RISCIX_MAGIC	cpu_to_le32(0x4a657320)
	__le32	date;
	struct riscix_part part[8];
};

#if defined(CONFIG_ACORN_PARTITION_CUMANA) || \
	defined(CONFIG_ACORN_PARTITION_ADFS)
static int riscix_partition(struct parsed_partitions *state,
			    unsigned long first_sect, int slot,
			    unsigned long nr_sects)
{
	Sector sect;
	struct riscix_record *rr;
	
	rr = read_part_sector(state, first_sect, &sect);
	if (!rr)
		return -1;

	strlcat(state->pp_buf, " [RISCiX]", PAGE_SIZE);


	if (rr->magic == RISCIX_MAGIC) {
		unsigned long size = nr_sects > 2 ? 2 : nr_sects;
		int part;

		strlcat(state->pp_buf, " <", PAGE_SIZE);

		put_partition(state, slot++, first_sect, size);
		for (part = 0; part < 8; part++) {
			if (rr->part[part].one &&
			    memcmp(rr->part[part].name, "All\0", 4)) {
				put_partition(state, slot++,
					le32_to_cpu(rr->part[part].start),
					le32_to_cpu(rr->part[part].length));
				strlcat(state->pp_buf, "(", PAGE_SIZE);
				strlcat(state->pp_buf, rr->part[part].name, PAGE_SIZE);
				strlcat(state->pp_buf, ")", PAGE_SIZE);
			}
		}

		strlcat(state->pp_buf, " >\n", PAGE_SIZE);
	} else {
		put_partition(state, slot++, first_sect, nr_sects);
	}

	put_dev_sector(sect);
	return slot;
}
#endif
#endif

#define LINUX_NATIVE_MAGIC 0xdeafa1de
#define LINUX_SWAP_MAGIC   0xdeafab1e

struct linux_part {
	__le32 magic;
	__le32 start_sect;
	__le32 nr_sects;
};

#if defined(CONFIG_ACORN_PARTITION_CUMANA) || \
	defined(CONFIG_ACORN_PARTITION_ADFS)
static int linux_partition(struct parsed_partitions *state,
			   unsigned long first_sect, int slot,
			   unsigned long nr_sects)
{
	Sector sect;
	struct linux_part *linuxp;
	unsigned long size = nr_sects > 2 ? 2 : nr_sects;

	strlcat(state->pp_buf, " [Linux]", PAGE_SIZE);

	put_partition(state, slot++, first_sect, size);

	linuxp = read_part_sector(state, first_sect, &sect);
	if (!linuxp)
		return -1;

	strlcat(state->pp_buf, " <", PAGE_SIZE);
	while (linuxp->magic == cpu_to_le32(LINUX_NATIVE_MAGIC) ||
	       linuxp->magic == cpu_to_le32(LINUX_SWAP_MAGIC)) {
		if (slot == state->limit)
			break;
		put_partition(state, slot++, first_sect +
				 le32_to_cpu(linuxp->start_sect),
				 le32_to_cpu(linuxp->nr_sects));
		linuxp ++;
	}
	strlcat(state->pp_buf, " >", PAGE_SIZE);

	put_dev_sector(sect);
	return slot;
}
#endif

#ifdef CONFIG_ACORN_PARTITION_CUMANA
int adfspart_check_CUMANA(struct parsed_partitions *state)
{
	unsigned long first_sector = 0;
	unsigned int start_blk = 0;
	Sector sect;
	unsigned char *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;
		unsigned int nr_sects;

		data = read_part_sector(state, start_blk * 2 + 6, &sect);
		if (!data)
			return -1;

		if (slot == state->limit)
			break;

		dr = adfs_partition(state, name, data, first_sector, slot++);
		if (!dr)
			break;

		name = NULL;

		nr_sects = (data[0x1fd] + (data[0x1fe] << 8)) *
			   (dr->heads + (dr->lowsector & 0x40 ? 1 : 0)) *
			   dr->secspertrack;

		if (!nr_sects)
			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)
{
	unsigned long start_sect, nr_sects, sectscyl, heads;
	Sector sect;
	unsigned char *data;
	struct adfs_discrecord *dr;
	unsigned char id;
	int slot = 1;

	data = read_part_sector(state, 6, &sect);
	if (!data)
		return -1;

	dr = adfs_partition(state, "ADFS", data, 0, slot++);
	if (!dr) {
		put_dev_sector(sect);
    		return 0;
	}

	heads = dr->heads + ((dr->lowsector >> 6) & 1);
	sectscyl = dr->secspertrack * heads;
	start_sect = ((data[0x1fe] << 8) + data[0x1fd]) * sectscyl;
	id = data[0x1fc] & 15;
	put_dev_sector(sect);

	/*
	 * Work out start of non-adfs partition.
	 */
	nr_sects = (state->bdev->bd_inode->i_size >> 9) - start_sect;

	if (start_sect) {
		switch (id) {
#ifdef CONFIG_ACORN_PARTITION_RISCIX
		case PARTITION_RISCIX_SCSI:
		case PARTITION_RISCIX_MFM:
			slot = riscix_partition(state, start_sect, slot,
						nr_sects);
			break;
#endif

		case PARTITION_LINUX:
			slot = linux_partition(state, start_sect, slot,
					       nr_sects);
			break;
		}
	}
	strlcat(state->pp_buf, "\n", PAGE_SIZE);
	return 1;
}
#endif

#ifdef CONFIG_ACORN_PARTITION_ICS

struct ics_part {
	__le32 start;
	__le32 size;
};

static int adfspart_check_ICSLinux(struct parsed_partitions *state,
				   unsigned long block)
{
	Sector sect;
	unsigned char *data = read_part_sector(state, block, &sect);
	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.
 */
static inline int valid_ics_sector(const unsigned char *data)
{
	unsigned long 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)
{
	const unsigned char *data;
	const struct ics_part *p;
	int slot;
	Sector sect;

	/*
	 * Try ICS style partitions - sector 0 contains partition info.
	 */
	data = read_part_sector(state, 0, &sect);
	if (!data)
	    	return -1;

	if (!valid_ics_sector(data)) {
	    	put_dev_sector(sect);
		return 0;
	}

	strlcat(state->pp_buf, " [ICS]", PAGE_SIZE);

	for (slot = 1, p = (const struct ics_part *)data; p->size; p++) {
		u32 start = le32_to_cpu(p->start);
		s32 size = le32_to_cpu(p->size); /* yes, it's signed. */

		if (slot == state->limit)
			break;

		/*
		 * 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);
	}

	put_dev_sector(sect);
	strlcat(state->pp_buf, "\n", PAGE_SIZE);
	return 1;
}
#endif

#ifdef CONFIG_ACORN_PARTITION_POWERTEC
struct ptec_part {
	__le32 unused1;
	__le32 unused2;
	__le32 start;
	__le32 size;
	__le32 unused5;
	char type[8];
};

static inline int valid_ptec_sector(const unsigned char *data)
{
	unsigned char 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;
	const unsigned char *data;
	const struct ptec_part *p;
	int slot = 1;
	int i;

	data = read_part_sector(state, 0, &sect);
	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 = (const struct 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);
	}

	put_dev_sector(sect);
	strlcat(state->pp_buf, "\n", PAGE_SIZE);
	return 1;
}
#endif

#ifdef CONFIG_ACORN_PARTITION_EESOX
struct eesox_part {
	char	magic[6];
	char	name[10];
	__le32	start;
	__le32	unused6;
	__le32	unused7;
	__le32	unused8;
};

/*
 * Guess who created this format?
 */
static const char eesox_name[] = {
	'N', 'e', 'i', 'l', ' ',
	'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' '
};

/*
 * 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;
	const unsigned char *data;
	unsigned char buffer[256];
	struct eesox_part *p;
	sector_t start = 0;
	int i, slot = 1;

	data = read_part_sector(state, 7, &sect);
	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;
	}

	if (i != 0) {
		sector_t size;

		size = get_capacity(state->bdev->bd_disk);
		put_partition(state, slot++, start, size - start);
		strlcat(state->pp_buf, "\n", PAGE_SIZE);
	}

	return i ? 1 : 0;
}
#endif
