2005-04-16 15:20:36 -07:00
/*
* fs / partitions / atari . 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 "atari.h"
/* ++guenther: this should be settable by the user ("make config")?.
*/
# define ICD_PARTS
/* check if a partition entry looks valid -- Atari format is assumed if at
least one of the primary entries is ok this way */
# define VALID_PARTITION(pi,hdsiz) \
( ( ( pi ) - > flg & 1 ) & & \
isalnum ( ( pi ) - > id [ 0 ] ) & & isalnum ( ( pi ) - > id [ 1 ] ) & & isalnum ( ( pi ) - > id [ 2 ] ) & & \
be32_to_cpu ( ( pi ) - > st ) < = ( hdsiz ) & & \
be32_to_cpu ( ( pi ) - > st ) + be32_to_cpu ( ( pi ) - > siz ) < = ( hdsiz ) )
static inline int OK_id ( char * s )
{
return memcmp ( s , " GEM " , 3 ) = = 0 | | memcmp ( s , " BGM " , 3 ) = = 0 | |
memcmp ( s , " LNX " , 3 ) = = 0 | | memcmp ( s , " SWP " , 3 ) = = 0 | |
memcmp ( s , " RAW " , 3 ) = = 0 ;
}
int atari_partition ( struct parsed_partitions * state , struct block_device * bdev )
{
Sector sect ;
struct rootsector * rs ;
struct partition_info * pi ;
u32 extensect ;
u32 hd_size ;
int slot ;
# ifdef ICD_PARTS
int part_fmt = 0 ; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
# endif
rs = ( struct rootsector * ) read_dev_sector ( bdev , 0 , & sect ) ;
if ( ! rs )
return - 1 ;
/* Verify this is an Atari rootsector: */
hd_size = bdev - > bd_inode - > i_size > > 9 ;
if ( ! VALID_PARTITION ( & rs - > part [ 0 ] , hd_size ) & &
! VALID_PARTITION ( & rs - > part [ 1 ] , hd_size ) & &
! VALID_PARTITION ( & rs - > part [ 2 ] , hd_size ) & &
! VALID_PARTITION ( & rs - > part [ 3 ] , hd_size ) ) {
/*
* if there ' s no valid primary partition , assume that no Atari
* format partition table ( there ' s no reliable magic or the like
* : - ( )
*/
put_dev_sector ( sect ) ;
return 0 ;
}
pi = & rs - > part [ 0 ] ;
printk ( " AHDI " ) ;
for ( slot = 1 ; pi < & rs - > part [ 4 ] & & slot < state - > limit ; slot + + , pi + + ) {
struct rootsector * xrs ;
Sector sect2 ;
ulong partsect ;
if ( ! ( pi - > flg & 1 ) )
continue ;
/* active partition */
if ( memcmp ( pi - > id , " XGM " , 3 ) ! = 0 ) {
/* we don't care about other id's */
put_partition ( state , slot , be32_to_cpu ( pi - > st ) ,
be32_to_cpu ( pi - > siz ) ) ;
continue ;
}
/* extension partition */
# ifdef ICD_PARTS
part_fmt = 1 ;
# endif
printk ( " XGM< " ) ;
partsect = extensect = be32_to_cpu ( pi - > st ) ;
while ( 1 ) {
xrs = ( struct rootsector * ) read_dev_sector ( bdev , partsect , & sect2 ) ;
if ( ! xrs ) {
printk ( " block %ld read failed \n " , partsect ) ;
put_dev_sector ( sect ) ;
2006-12-06 20:35:16 -08:00
return - 1 ;
2005-04-16 15:20:36 -07:00
}
/* ++roman: sanity check: bit 0 of flg field must be set */
if ( ! ( xrs - > part [ 0 ] . flg & 1 ) ) {
printk ( " \n First sub-partition in extended partition is not valid! \n " ) ;
put_dev_sector ( sect2 ) ;
break ;
}
put_partition ( state , slot ,
partsect + be32_to_cpu ( xrs - > part [ 0 ] . st ) ,
be32_to_cpu ( xrs - > part [ 0 ] . siz ) ) ;
if ( ! ( xrs - > part [ 1 ] . flg & 1 ) ) {
/* end of linked partition list */
put_dev_sector ( sect2 ) ;
break ;
}
if ( memcmp ( xrs - > part [ 1 ] . id , " XGM " , 3 ) ! = 0 ) {
printk ( " \n ID of extended partition is not XGM! \n " ) ;
put_dev_sector ( sect2 ) ;
break ;
}
partsect = be32_to_cpu ( xrs - > part [ 1 ] . st ) + extensect ;
put_dev_sector ( sect2 ) ;
if ( + + slot = = state - > limit ) {
printk ( " \n Maximum number of partitions reached! \n " ) ;
break ;
}
}
printk ( " > " ) ;
}
# ifdef ICD_PARTS
if ( part_fmt ! = 1 ) { /* no extended partitions -> test ICD-format */
pi = & rs - > icdpart [ 0 ] ;
/* sanity check: no ICD format if first partition invalid */
if ( OK_id ( pi - > id ) ) {
printk ( " ICD< " ) ;
for ( ; pi < & rs - > icdpart [ 8 ] & & slot < state - > limit ; slot + + , pi + + ) {
/* accept only GEM,BGM,RAW,LNX,SWP partitions */
if ( ! ( ( pi - > flg & 1 ) & & OK_id ( pi - > id ) ) )
continue ;
part_fmt = 2 ;
put_partition ( state , slot ,
be32_to_cpu ( pi - > st ) ,
be32_to_cpu ( pi - > siz ) ) ;
}
printk ( " > " ) ;
}
}
# endif
put_dev_sector ( sect ) ;
printk ( " \n " ) ;
return 1 ;
}