2005-04-17 02:20:36 +04:00
/*
* fs / partitions / mac . c
*
* Code extracted from drivers / block / genhd . c
* Copyright ( C ) 1991 - 1998 Linus Torvalds
* Re - organised Feb 1998 Russell King
*/
# include <linux/ctype.h>
# include "check.h"
# include "mac.h"
# ifdef CONFIG_PPC_PMAC
2006-03-28 16:15:54 +04:00
# include <asm/machdep.h>
2005-04-17 02:20:36 +04:00
extern void note_bootable_part ( dev_t dev , int part , int goodness ) ;
# endif
/*
* Code to understand MacOS partition tables .
*/
static inline void mac_fix_string ( char * stg , int len )
{
int i ;
for ( i = len - 1 ; i > = 0 & & stg [ i ] = = ' ' ; i - - )
stg [ i ] = 0 ;
}
2010-05-15 22:09:30 +04:00
int mac_partition ( struct parsed_partitions * state )
2005-04-17 02:20:36 +04:00
{
Sector sect ;
unsigned char * data ;
2011-02-18 00:27:40 +03:00
int slot , blocks_in_map ;
2005-04-17 02:20:36 +04:00
unsigned secsize ;
# ifdef CONFIG_PPC_PMAC
int found_root = 0 ;
int found_root_goodness = 0 ;
# endif
struct mac_partition * part ;
struct mac_driver_desc * md ;
/* Get 0th block and look at the first partition map entry. */
2010-05-15 22:09:30 +04:00
md = read_part_sector ( state , 0 , & sect ) ;
2005-04-17 02:20:36 +04:00
if ( ! md )
return - 1 ;
if ( be16_to_cpu ( md - > signature ) ! = MAC_DRIVER_MAGIC ) {
put_dev_sector ( sect ) ;
return 0 ;
}
secsize = be16_to_cpu ( md - > block_size ) ;
put_dev_sector ( sect ) ;
2010-05-15 22:09:30 +04:00
data = read_part_sector ( state , secsize / 512 , & sect ) ;
2005-04-17 02:20:36 +04:00
if ( ! data )
return - 1 ;
part = ( struct mac_partition * ) ( data + secsize % 512 ) ;
if ( be16_to_cpu ( part - > signature ) ! = MAC_PARTITION_MAGIC ) {
put_dev_sector ( sect ) ;
return 0 ; /* not a MacOS disk */
}
blocks_in_map = be32_to_cpu ( part - > map_count ) ;
2011-02-18 00:27:40 +03:00
if ( blocks_in_map < 0 | | blocks_in_map > = DISK_MAX_PARTS ) {
put_dev_sector ( sect ) ;
return 0 ;
}
2013-02-28 05:05:18 +04:00
if ( blocks_in_map > = state - > limit )
blocks_in_map = state - > limit - 1 ;
2011-02-18 00:27:40 +03:00
strlcat ( state - > pp_buf , " [mac] " , PAGE_SIZE ) ;
for ( slot = 1 ; slot < = blocks_in_map ; + + slot ) {
int pos = slot * secsize ;
2005-04-17 02:20:36 +04:00
put_dev_sector ( sect ) ;
2010-05-15 22:09:30 +04:00
data = read_part_sector ( state , pos / 512 , & sect ) ;
2005-04-17 02:20:36 +04:00
if ( ! data )
return - 1 ;
part = ( struct mac_partition * ) ( data + pos % 512 ) ;
if ( be16_to_cpu ( part - > signature ) ! = MAC_PARTITION_MAGIC )
break ;
put_partition ( state , slot ,
be32_to_cpu ( part - > start_block ) * ( secsize / 512 ) ,
be32_to_cpu ( part - > block_count ) * ( secsize / 512 ) ) ;
2006-12-04 18:45:46 +03:00
if ( ! strnicmp ( part - > type , " Linux_RAID " , 10 ) )
2010-04-18 02:28:09 +04:00
state - > parts [ slot ] . flags = ADDPART_FLAG_RAID ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_PPC_PMAC
/*
* If this is the first bootable partition , tell the
* setup code , in case it wants to make this the root .
*/
2006-03-28 16:15:54 +04:00
if ( machine_is ( powermac ) ) {
2005-04-17 02:20:36 +04:00
int goodness = 0 ;
mac_fix_string ( part - > processor , 16 ) ;
mac_fix_string ( part - > name , 32 ) ;
mac_fix_string ( part - > type , 32 ) ;
if ( ( be32_to_cpu ( part - > status ) & MAC_STATUS_BOOTABLE )
& & strcasecmp ( part - > processor , " powerpc " ) = = 0 )
goodness + + ;
if ( strcasecmp ( part - > type , " Apple_UNIX_SVR2 " ) = = 0
| | ( strnicmp ( part - > type , " Linux " , 5 ) = = 0
& & strcasecmp ( part - > type , " Linux_swap " ) ! = 0 ) ) {
int i , l ;
goodness + + ;
l = strlen ( part - > name ) ;
if ( strcmp ( part - > name , " / " ) = = 0 )
goodness + + ;
for ( i = 0 ; i < = l - 4 ; + + i ) {
if ( strnicmp ( part - > name + i , " root " ,
4 ) = = 0 ) {
goodness + = 2 ;
break ;
}
}
if ( strnicmp ( part - > name , " swap " , 4 ) = = 0 )
goodness - - ;
}
if ( goodness > found_root_goodness ) {
2011-02-18 00:27:40 +03:00
found_root = slot ;
2005-04-17 02:20:36 +04:00
found_root_goodness = goodness ;
}
}
# endif /* CONFIG_PPC_PMAC */
}
# ifdef CONFIG_PPC_PMAC
if ( found_root_goodness )
2010-05-15 22:09:30 +04:00
note_bootable_part ( state - > bdev - > bd_dev , found_root ,
found_root_goodness ) ;
2005-04-17 02:20:36 +04:00
# endif
put_dev_sector ( sect ) ;
2010-08-11 05:03:14 +04:00
strlcat ( state - > pp_buf , " \n " , PAGE_SIZE ) ;
2005-04-17 02:20:36 +04:00
return 1 ;
}