2005-04-17 02:20:36 +04:00
/*
* fs / partitions / sun . c
*
* Code extracted from drivers / block / genhd . c
*
* Copyright ( C ) 1991 - 1998 Linus Torvalds
* Re - organised Feb 1998 Russell King
*/
# include "check.h"
# include "sun.h"
2010-05-15 22:09:30 +04:00
int sun_partition ( struct parsed_partitions * state )
2005-04-17 02:20:36 +04:00
{
int i ;
__be16 csum ;
int slot = 1 ;
__be16 * ush ;
Sector sect ;
struct sun_disklabel {
unsigned char info [ 128 ] ; /* Informative text string */
2007-07-26 11:17:22 +04:00
struct sun_vtoc {
__be32 version ; /* Layout version */
char volume [ 8 ] ; /* Volume name */
__be16 nparts ; /* Number of partitions */
struct sun_info { /* Partition hdrs, sec 2 */
__be16 id ;
__be16 flags ;
} infos [ 8 ] ;
__be16 padding ; /* Alignment padding */
__be32 bootinfo [ 3 ] ; /* Info needed by mboot */
__be32 sanity ; /* To verify vtoc sanity */
__be32 reserved [ 10 ] ; /* Free space */
__be32 timestamp [ 8 ] ; /* Partition timestamp */
} vtoc ;
__be32 write_reinstruct ; /* sectors to skip, writes */
__be32 read_reinstruct ; /* sectors to skip, reads */
unsigned char spare [ 148 ] ; /* Padding */
2005-04-17 02:20:36 +04:00
__be16 rspeed ; /* Disk rotational speed */
__be16 pcylcount ; /* Physical cylinder count */
__be16 sparecyl ; /* extra sects per cylinder */
2007-07-26 11:17:22 +04:00
__be16 obs1 ; /* gap1 */
__be16 obs2 ; /* gap2 */
2005-04-17 02:20:36 +04:00
__be16 ilfact ; /* Interleave factor */
__be16 ncyl ; /* Data cylinder count */
__be16 nacyl ; /* Alt. cylinder count */
__be16 ntrks ; /* Tracks per cylinder */
__be16 nsect ; /* Sectors per track */
2007-07-26 11:17:22 +04:00
__be16 obs3 ; /* bhead - Label head offset */
__be16 obs4 ; /* ppart - Physical Partition */
2005-04-17 02:20:36 +04:00
struct sun_partition {
__be32 start_cylinder ;
__be32 num_sectors ;
} partitions [ 8 ] ;
__be16 magic ; /* Magic number */
__be16 csum ; /* Label xor'd checksum */
2007-07-26 11:17:22 +04:00
} * label ;
2005-04-17 02:20:36 +04:00
struct sun_partition * p ;
unsigned long spc ;
char b [ BDEVNAME_SIZE ] ;
2007-07-26 11:17:22 +04:00
int use_vtoc ;
int nparts ;
2005-04-17 02:20:36 +04:00
2010-05-15 22:09:30 +04:00
label = read_part_sector ( state , 0 , & sect ) ;
2005-04-17 02:20:36 +04:00
if ( ! label )
return - 1 ;
p = label - > partitions ;
if ( be16_to_cpu ( label - > magic ) ! = SUN_LABEL_MAGIC ) {
/* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n",
bdevname ( bdev , b ) , be16_to_cpu ( label - > magic ) ) ; */
put_dev_sector ( sect ) ;
return 0 ;
}
/* Look at the checksum */
ush = ( ( __be16 * ) ( label + 1 ) ) - 1 ;
for ( csum = 0 ; ush > = ( ( __be16 * ) label ) ; )
csum ^ = * ush - - ;
if ( csum ) {
printk ( " Dev %s Sun disklabel: Csum bad, label corrupted \n " ,
2010-05-15 22:09:30 +04:00
bdevname ( state - > bdev , b ) ) ;
2005-04-17 02:20:36 +04:00
put_dev_sector ( sect ) ;
return 0 ;
}
2007-07-26 11:17:22 +04:00
/* Check to see if we can use the VTOC table */
use_vtoc = ( ( be32_to_cpu ( label - > vtoc . sanity ) = = SUN_VTOC_SANITY ) & &
( be32_to_cpu ( label - > vtoc . version ) = = 1 ) & &
( be16_to_cpu ( label - > vtoc . nparts ) < = 8 ) ) ;
/* Use 8 partition entries if not specified in validated VTOC */
nparts = ( use_vtoc ) ? be16_to_cpu ( label - > vtoc . nparts ) : 8 ;
/*
* So that old Linux - Sun partitions continue to work ,
* alow the VTOC to be used under the additional condition . . .
*/
2007-10-14 22:34:50 +04:00
use_vtoc = use_vtoc | | ! ( label - > vtoc . sanity | |
label - > vtoc . version | | label - > vtoc . nparts ) ;
2005-04-17 02:20:36 +04:00
spc = be16_to_cpu ( label - > ntrks ) * be16_to_cpu ( label - > nsect ) ;
2007-07-26 11:17:22 +04:00
for ( i = 0 ; i < nparts ; i + + , p + + ) {
2005-04-17 02:20:36 +04:00
unsigned long st_sector ;
2006-08-26 02:58:57 +04:00
unsigned int num_sectors ;
2005-04-17 02:20:36 +04:00
st_sector = be32_to_cpu ( p - > start_cylinder ) * spc ;
num_sectors = be32_to_cpu ( p - > num_sectors ) ;
if ( num_sectors ) {
put_partition ( state , slot , st_sector , num_sectors ) ;
2007-02-11 10:50:00 +03:00
state - > parts [ slot ] . flags = 0 ;
2007-07-26 11:17:22 +04:00
if ( use_vtoc ) {
if ( be16_to_cpu ( label - > vtoc . infos [ i ] . id ) = = LINUX_RAID_PARTITION )
state - > parts [ slot ] . flags | = ADDPART_FLAG_RAID ;
else if ( be16_to_cpu ( label - > vtoc . infos [ i ] . id ) = = SUN_WHOLE_DISK )
state - > parts [ slot ] . flags | = ADDPART_FLAG_WHOLEDISK ;
}
2005-04-17 02:20:36 +04:00
}
slot + + ;
}
2010-08-11 05:03:14 +04:00
strlcat ( state - > pp_buf , " \n " , PAGE_SIZE ) ;
2005-04-17 02:20:36 +04:00
put_dev_sector ( sect ) ;
return 1 ;
}