162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * fs/partitions/sgi.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Code extracted from drivers/block/genhd.c 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "check.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define SGI_LABEL_MAGIC 0x0be5a941 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cienum { 1362306a36Sopenharmony_ci LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ 1462306a36Sopenharmony_ci}; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct sgi_disklabel { 1762306a36Sopenharmony_ci __be32 magic_mushroom; /* Big fat spliff... */ 1862306a36Sopenharmony_ci __be16 root_part_num; /* Root partition number */ 1962306a36Sopenharmony_ci __be16 swap_part_num; /* Swap partition number */ 2062306a36Sopenharmony_ci s8 boot_file[16]; /* Name of boot file for ARCS */ 2162306a36Sopenharmony_ci u8 _unused0[48]; /* Device parameter useless crapola.. */ 2262306a36Sopenharmony_ci struct sgi_volume { 2362306a36Sopenharmony_ci s8 name[8]; /* Name of volume */ 2462306a36Sopenharmony_ci __be32 block_num; /* Logical block number */ 2562306a36Sopenharmony_ci __be32 num_bytes; /* How big, in bytes */ 2662306a36Sopenharmony_ci } volume[15]; 2762306a36Sopenharmony_ci struct sgi_partition { 2862306a36Sopenharmony_ci __be32 num_blocks; /* Size in logical blocks */ 2962306a36Sopenharmony_ci __be32 first_block; /* First logical block */ 3062306a36Sopenharmony_ci __be32 type; /* Type of this partition */ 3162306a36Sopenharmony_ci } partitions[16]; 3262306a36Sopenharmony_ci __be32 csum; /* Disk label checksum */ 3362306a36Sopenharmony_ci __be32 _unused1; /* Padding */ 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciint sgi_partition(struct parsed_partitions *state) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci int i, csum; 3962306a36Sopenharmony_ci __be32 magic; 4062306a36Sopenharmony_ci int slot = 1; 4162306a36Sopenharmony_ci unsigned int start, blocks; 4262306a36Sopenharmony_ci __be32 *ui, cs; 4362306a36Sopenharmony_ci Sector sect; 4462306a36Sopenharmony_ci struct sgi_disklabel *label; 4562306a36Sopenharmony_ci struct sgi_partition *p; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci label = read_part_sector(state, 0, §); 4862306a36Sopenharmony_ci if (!label) 4962306a36Sopenharmony_ci return -1; 5062306a36Sopenharmony_ci p = &label->partitions[0]; 5162306a36Sopenharmony_ci magic = label->magic_mushroom; 5262306a36Sopenharmony_ci if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { 5362306a36Sopenharmony_ci /*printk("Dev %s SGI disklabel: bad magic %08x\n", 5462306a36Sopenharmony_ci state->disk->disk_name, be32_to_cpu(magic));*/ 5562306a36Sopenharmony_ci put_dev_sector(sect); 5662306a36Sopenharmony_ci return 0; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci ui = ((__be32 *) (label + 1)) - 1; 5962306a36Sopenharmony_ci for(csum = 0; ui >= ((__be32 *) label);) { 6062306a36Sopenharmony_ci cs = *ui--; 6162306a36Sopenharmony_ci csum += be32_to_cpu(cs); 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci if(csum) { 6462306a36Sopenharmony_ci printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", 6562306a36Sopenharmony_ci state->disk->disk_name); 6662306a36Sopenharmony_ci put_dev_sector(sect); 6762306a36Sopenharmony_ci return 0; 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci /* All SGI disk labels have 16 partitions, disks under Linux only 7062306a36Sopenharmony_ci * have 15 minor's. Luckily there are always a few zero length 7162306a36Sopenharmony_ci * partitions which we don't care about so we never overflow the 7262306a36Sopenharmony_ci * current_minor. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_ci for(i = 0; i < 16; i++, p++) { 7562306a36Sopenharmony_ci blocks = be32_to_cpu(p->num_blocks); 7662306a36Sopenharmony_ci start = be32_to_cpu(p->first_block); 7762306a36Sopenharmony_ci if (blocks) { 7862306a36Sopenharmony_ci put_partition(state, slot, start, blocks); 7962306a36Sopenharmony_ci if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) 8062306a36Sopenharmony_ci state->parts[slot].flags = ADDPART_FLAG_RAID; 8162306a36Sopenharmony_ci } 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