18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * fs/partitions/sgi.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Code extracted from drivers/block/genhd.c 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "check.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define SGI_LABEL_MAGIC 0x0be5a941 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cienum { 138c2ecf20Sopenharmony_ci LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ 148c2ecf20Sopenharmony_ci}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct sgi_disklabel { 178c2ecf20Sopenharmony_ci __be32 magic_mushroom; /* Big fat spliff... */ 188c2ecf20Sopenharmony_ci __be16 root_part_num; /* Root partition number */ 198c2ecf20Sopenharmony_ci __be16 swap_part_num; /* Swap partition number */ 208c2ecf20Sopenharmony_ci s8 boot_file[16]; /* Name of boot file for ARCS */ 218c2ecf20Sopenharmony_ci u8 _unused0[48]; /* Device parameter useless crapola.. */ 228c2ecf20Sopenharmony_ci struct sgi_volume { 238c2ecf20Sopenharmony_ci s8 name[8]; /* Name of volume */ 248c2ecf20Sopenharmony_ci __be32 block_num; /* Logical block number */ 258c2ecf20Sopenharmony_ci __be32 num_bytes; /* How big, in bytes */ 268c2ecf20Sopenharmony_ci } volume[15]; 278c2ecf20Sopenharmony_ci struct sgi_partition { 288c2ecf20Sopenharmony_ci __be32 num_blocks; /* Size in logical blocks */ 298c2ecf20Sopenharmony_ci __be32 first_block; /* First logical block */ 308c2ecf20Sopenharmony_ci __be32 type; /* Type of this partition */ 318c2ecf20Sopenharmony_ci } partitions[16]; 328c2ecf20Sopenharmony_ci __be32 csum; /* Disk label checksum */ 338c2ecf20Sopenharmony_ci __be32 _unused1; /* Padding */ 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ciint sgi_partition(struct parsed_partitions *state) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci int i, csum; 398c2ecf20Sopenharmony_ci __be32 magic; 408c2ecf20Sopenharmony_ci int slot = 1; 418c2ecf20Sopenharmony_ci unsigned int start, blocks; 428c2ecf20Sopenharmony_ci __be32 *ui, cs; 438c2ecf20Sopenharmony_ci Sector sect; 448c2ecf20Sopenharmony_ci struct sgi_disklabel *label; 458c2ecf20Sopenharmony_ci struct sgi_partition *p; 468c2ecf20Sopenharmony_ci char b[BDEVNAME_SIZE]; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci label = read_part_sector(state, 0, §); 498c2ecf20Sopenharmony_ci if (!label) 508c2ecf20Sopenharmony_ci return -1; 518c2ecf20Sopenharmony_ci p = &label->partitions[0]; 528c2ecf20Sopenharmony_ci magic = label->magic_mushroom; 538c2ecf20Sopenharmony_ci if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { 548c2ecf20Sopenharmony_ci /*printk("Dev %s SGI disklabel: bad magic %08x\n", 558c2ecf20Sopenharmony_ci bdevname(bdev, b), be32_to_cpu(magic));*/ 568c2ecf20Sopenharmony_ci put_dev_sector(sect); 578c2ecf20Sopenharmony_ci return 0; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci ui = ((__be32 *) (label + 1)) - 1; 608c2ecf20Sopenharmony_ci for(csum = 0; ui >= ((__be32 *) label);) { 618c2ecf20Sopenharmony_ci cs = *ui--; 628c2ecf20Sopenharmony_ci csum += be32_to_cpu(cs); 638c2ecf20Sopenharmony_ci } 648c2ecf20Sopenharmony_ci if(csum) { 658c2ecf20Sopenharmony_ci printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", 668c2ecf20Sopenharmony_ci bdevname(state->bdev, b)); 678c2ecf20Sopenharmony_ci put_dev_sector(sect); 688c2ecf20Sopenharmony_ci return 0; 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci /* All SGI disk labels have 16 partitions, disks under Linux only 718c2ecf20Sopenharmony_ci * have 15 minor's. Luckily there are always a few zero length 728c2ecf20Sopenharmony_ci * partitions which we don't care about so we never overflow the 738c2ecf20Sopenharmony_ci * current_minor. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci for(i = 0; i < 16; i++, p++) { 768c2ecf20Sopenharmony_ci blocks = be32_to_cpu(p->num_blocks); 778c2ecf20Sopenharmony_ci start = be32_to_cpu(p->first_block); 788c2ecf20Sopenharmony_ci if (blocks) { 798c2ecf20Sopenharmony_ci put_partition(state, slot, start, blocks); 808c2ecf20Sopenharmony_ci if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) 818c2ecf20Sopenharmony_ci state->parts[slot].flags = ADDPART_FLAG_RAID; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci slot++; 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci strlcat(state->pp_buf, "\n", PAGE_SIZE); 868c2ecf20Sopenharmony_ci put_dev_sector(sect); 878c2ecf20Sopenharmony_ci return 1; 888c2ecf20Sopenharmony_ci} 89