162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  fs/partitions/sysv68.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 2007 Philippe De Muyter <phdm@macqel.be>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "check.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci *	Volume ID structure: on first 256-bytes sector of disk
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistruct volumeid {
1562306a36Sopenharmony_ci	u8	vid_unused[248];
1662306a36Sopenharmony_ci	u8	vid_mac[8];	/* ASCII string "MOTOROLA" */
1762306a36Sopenharmony_ci};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci *	config block: second 256-bytes sector on disk
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistruct dkconfig {
2462306a36Sopenharmony_ci	u8	ios_unused0[128];
2562306a36Sopenharmony_ci	__be32	ios_slcblk;	/* Slice table block number */
2662306a36Sopenharmony_ci	__be16	ios_slccnt;	/* Number of entries in slice table */
2762306a36Sopenharmony_ci	u8	ios_unused1[122];
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci *	combined volumeid and dkconfig block
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct dkblk0 {
3562306a36Sopenharmony_ci	struct volumeid dk_vid;
3662306a36Sopenharmony_ci	struct dkconfig dk_ios;
3762306a36Sopenharmony_ci};
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/*
4062306a36Sopenharmony_ci *	Slice Table Structure
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistruct slice {
4462306a36Sopenharmony_ci	__be32	nblocks;		/* slice size (in blocks) */
4562306a36Sopenharmony_ci	__be32	blkoff;			/* block offset of slice */
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciint sysv68_partition(struct parsed_partitions *state)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	int i, slices;
5262306a36Sopenharmony_ci	int slot = 1;
5362306a36Sopenharmony_ci	Sector sect;
5462306a36Sopenharmony_ci	unsigned char *data;
5562306a36Sopenharmony_ci	struct dkblk0 *b;
5662306a36Sopenharmony_ci	struct slice *slice;
5762306a36Sopenharmony_ci	char tmp[64];
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	data = read_part_sector(state, 0, &sect);
6062306a36Sopenharmony_ci	if (!data)
6162306a36Sopenharmony_ci		return -1;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	b = (struct dkblk0 *)data;
6462306a36Sopenharmony_ci	if (memcmp(b->dk_vid.vid_mac, "MOTOROLA", sizeof(b->dk_vid.vid_mac))) {
6562306a36Sopenharmony_ci		put_dev_sector(sect);
6662306a36Sopenharmony_ci		return 0;
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci	slices = be16_to_cpu(b->dk_ios.ios_slccnt);
6962306a36Sopenharmony_ci	i = be32_to_cpu(b->dk_ios.ios_slcblk);
7062306a36Sopenharmony_ci	put_dev_sector(sect);
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	data = read_part_sector(state, i, &sect);
7362306a36Sopenharmony_ci	if (!data)
7462306a36Sopenharmony_ci		return -1;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	slices -= 1; /* last slice is the whole disk */
7762306a36Sopenharmony_ci	snprintf(tmp, sizeof(tmp), "sysV68: %s(s%u)", state->name, slices);
7862306a36Sopenharmony_ci	strlcat(state->pp_buf, tmp, PAGE_SIZE);
7962306a36Sopenharmony_ci	slice = (struct slice *)data;
8062306a36Sopenharmony_ci	for (i = 0; i < slices; i++, slice++) {
8162306a36Sopenharmony_ci		if (slot == state->limit)
8262306a36Sopenharmony_ci			break;
8362306a36Sopenharmony_ci		if (be32_to_cpu(slice->nblocks)) {
8462306a36Sopenharmony_ci			put_partition(state, slot,
8562306a36Sopenharmony_ci				be32_to_cpu(slice->blkoff),
8662306a36Sopenharmony_ci				be32_to_cpu(slice->nblocks));
8762306a36Sopenharmony_ci			snprintf(tmp, sizeof(tmp), "(s%u)", i);
8862306a36Sopenharmony_ci			strlcat(state->pp_buf, tmp, PAGE_SIZE);
8962306a36Sopenharmony_ci		}
9062306a36Sopenharmony_ci		slot++;
9162306a36Sopenharmony_ci	}
9262306a36Sopenharmony_ci	strlcat(state->pp_buf, "\n", PAGE_SIZE);
9362306a36Sopenharmony_ci	put_dev_sector(sect);
9462306a36Sopenharmony_ci	return 1;
9562306a36Sopenharmony_ci}
96