162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  fs/partitions/osf.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Code extracted from drivers/block/genhd.c
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *  Copyright (C) 1991-1998  Linus Torvalds
862306a36Sopenharmony_ci *  Re-organised Feb 1998 Russell King
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "check.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define MAX_OSF_PARTITIONS 18
1462306a36Sopenharmony_ci#define DISKLABELMAGIC (0x82564557UL)
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciint osf_partition(struct parsed_partitions *state)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	int i;
1962306a36Sopenharmony_ci	int slot = 1;
2062306a36Sopenharmony_ci	unsigned int npartitions;
2162306a36Sopenharmony_ci	Sector sect;
2262306a36Sopenharmony_ci	unsigned char *data;
2362306a36Sopenharmony_ci	struct disklabel {
2462306a36Sopenharmony_ci		__le32 d_magic;
2562306a36Sopenharmony_ci		__le16 d_type,d_subtype;
2662306a36Sopenharmony_ci		u8 d_typename[16];
2762306a36Sopenharmony_ci		u8 d_packname[16];
2862306a36Sopenharmony_ci		__le32 d_secsize;
2962306a36Sopenharmony_ci		__le32 d_nsectors;
3062306a36Sopenharmony_ci		__le32 d_ntracks;
3162306a36Sopenharmony_ci		__le32 d_ncylinders;
3262306a36Sopenharmony_ci		__le32 d_secpercyl;
3362306a36Sopenharmony_ci		__le32 d_secprtunit;
3462306a36Sopenharmony_ci		__le16 d_sparespertrack;
3562306a36Sopenharmony_ci		__le16 d_sparespercyl;
3662306a36Sopenharmony_ci		__le32 d_acylinders;
3762306a36Sopenharmony_ci		__le16 d_rpm, d_interleave, d_trackskew, d_cylskew;
3862306a36Sopenharmony_ci		__le32 d_headswitch, d_trkseek, d_flags;
3962306a36Sopenharmony_ci		__le32 d_drivedata[5];
4062306a36Sopenharmony_ci		__le32 d_spare[5];
4162306a36Sopenharmony_ci		__le32 d_magic2;
4262306a36Sopenharmony_ci		__le16 d_checksum;
4362306a36Sopenharmony_ci		__le16 d_npartitions;
4462306a36Sopenharmony_ci		__le32 d_bbsize, d_sbsize;
4562306a36Sopenharmony_ci		struct d_partition {
4662306a36Sopenharmony_ci			__le32 p_size;
4762306a36Sopenharmony_ci			__le32 p_offset;
4862306a36Sopenharmony_ci			__le32 p_fsize;
4962306a36Sopenharmony_ci			u8  p_fstype;
5062306a36Sopenharmony_ci			u8  p_frag;
5162306a36Sopenharmony_ci			__le16 p_cpg;
5262306a36Sopenharmony_ci		} d_partitions[MAX_OSF_PARTITIONS];
5362306a36Sopenharmony_ci	} * label;
5462306a36Sopenharmony_ci	struct d_partition * partition;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	data = read_part_sector(state, 0, &sect);
5762306a36Sopenharmony_ci	if (!data)
5862306a36Sopenharmony_ci		return -1;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	label = (struct disklabel *) (data+64);
6162306a36Sopenharmony_ci	partition = label->d_partitions;
6262306a36Sopenharmony_ci	if (le32_to_cpu(label->d_magic) != DISKLABELMAGIC) {
6362306a36Sopenharmony_ci		put_dev_sector(sect);
6462306a36Sopenharmony_ci		return 0;
6562306a36Sopenharmony_ci	}
6662306a36Sopenharmony_ci	if (le32_to_cpu(label->d_magic2) != DISKLABELMAGIC) {
6762306a36Sopenharmony_ci		put_dev_sector(sect);
6862306a36Sopenharmony_ci		return 0;
6962306a36Sopenharmony_ci	}
7062306a36Sopenharmony_ci	npartitions = le16_to_cpu(label->d_npartitions);
7162306a36Sopenharmony_ci	if (npartitions > MAX_OSF_PARTITIONS) {
7262306a36Sopenharmony_ci		put_dev_sector(sect);
7362306a36Sopenharmony_ci		return 0;
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci	for (i = 0 ; i < npartitions; i++, partition++) {
7662306a36Sopenharmony_ci		if (slot == state->limit)
7762306a36Sopenharmony_ci		        break;
7862306a36Sopenharmony_ci		if (le32_to_cpu(partition->p_size))
7962306a36Sopenharmony_ci			put_partition(state, slot,
8062306a36Sopenharmony_ci				le32_to_cpu(partition->p_offset),
8162306a36Sopenharmony_ci				le32_to_cpu(partition->p_size));
8262306a36Sopenharmony_ci		slot++;
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci	strlcat(state->pp_buf, "\n", PAGE_SIZE);
8562306a36Sopenharmony_ci	put_dev_sector(sect);
8662306a36Sopenharmony_ci	return 1;
8762306a36Sopenharmony_ci}
88