|  | @@ -219,14 +219,13 @@ static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch,
 | 
		
	
		
			
			| 219 | 219 |  	struct master_boot_record *mbr = scratch;
 | 
		
	
		
			
			| 220 | 220 |  	struct partition_table_entry *partition;
 | 
		
	
		
			
			| 221 | 221 |  	unsigned int i;
 | 
		
	
		
			
			|  | 222 | +	unsigned int start_cylinder;
 | 
		
	
		
			
			|  | 223 | +	unsigned int start_head;
 | 
		
	
		
			
			|  | 224 | +	unsigned int start_sector;
 | 
		
	
		
			
			| 222 | 225 |  	unsigned int end_head;
 | 
		
	
		
			
			| 223 | 226 |  	unsigned int end_sector;
 | 
		
	
		
			
			| 224 | 227 |  	int rc;
 | 
		
	
		
			
			| 225 | 228 |  
 | 
		
	
		
			
			| 226 |  | -	/* Default guess is xx/255/63 */
 | 
		
	
		
			
			| 227 |  | -	*heads = 255;
 | 
		
	
		
			
			| 228 |  | -	*sectors = 63;
 | 
		
	
		
			
			| 229 |  | -
 | 
		
	
		
			
			| 230 | 229 |  	/* Read partition table */
 | 
		
	
		
			
			| 231 | 230 |  	if ( ( rc = sandev_rw ( sandev, 0, 1, virt_to_user ( mbr ),
 | 
		
	
		
			
			| 232 | 231 |  				block_read ) ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -244,19 +243,54 @@ static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch,
 | 
		
	
		
			
			| 244 | 243 |  	 * heads and sectors_per_track if we find any used
 | 
		
	
		
			
			| 245 | 244 |  	 * partitions.
 | 
		
	
		
			
			| 246 | 245 |  	 */
 | 
		
	
		
			
			|  | 246 | +	*heads = 0;
 | 
		
	
		
			
			|  | 247 | +	*sectors = 0;
 | 
		
	
		
			
			| 247 | 248 |  	for ( i = 0 ; i < 4 ; i++ ) {
 | 
		
	
		
			
			|  | 249 | +
 | 
		
	
		
			
			|  | 250 | +		/* Skip empty partitions */
 | 
		
	
		
			
			| 248 | 251 |  		partition = &mbr->partitions[i];
 | 
		
	
		
			
			|  | 252 | +		if ( ! partition->type )
 | 
		
	
		
			
			|  | 253 | +			continue;
 | 
		
	
		
			
			|  | 254 | +
 | 
		
	
		
			
			|  | 255 | +		/* If partition starts on cylinder 0 then we can
 | 
		
	
		
			
			|  | 256 | +		 * unambiguously determine the number of sectors.
 | 
		
	
		
			
			|  | 257 | +		 */
 | 
		
	
		
			
			|  | 258 | +		start_cylinder = PART_CYLINDER ( partition->chs_start );
 | 
		
	
		
			
			|  | 259 | +		start_head = PART_HEAD ( partition->chs_start );
 | 
		
	
		
			
			|  | 260 | +		start_sector = PART_SECTOR ( partition->chs_start );
 | 
		
	
		
			
			|  | 261 | +		if ( ( start_cylinder == 0 ) && ( start_head != 0 ) ) {
 | 
		
	
		
			
			|  | 262 | +			*sectors = ( ( partition->start + 1 - start_sector ) /
 | 
		
	
		
			
			|  | 263 | +				     start_head );
 | 
		
	
		
			
			|  | 264 | +			DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
 | 
		
	
		
			
			|  | 265 | +			       "xx/xx/%d based on partition %d\n",
 | 
		
	
		
			
			|  | 266 | +			       sandev->drive, *sectors, ( i + 1 ) );
 | 
		
	
		
			
			|  | 267 | +		}
 | 
		
	
		
			
			|  | 268 | +
 | 
		
	
		
			
			|  | 269 | +		/* If partition ends on a higher head or sector number
 | 
		
	
		
			
			|  | 270 | +		 * than our current guess, then increase the guess.
 | 
		
	
		
			
			|  | 271 | +		 */
 | 
		
	
		
			
			| 249 | 272 |  		end_head = PART_HEAD ( partition->chs_end );
 | 
		
	
		
			
			| 250 | 273 |  		end_sector = PART_SECTOR ( partition->chs_end );
 | 
		
	
		
			
			| 251 |  | -		if ( ! ( partition->type && end_head && end_sector ) )
 | 
		
	
		
			
			| 252 |  | -			continue;
 | 
		
	
		
			
			| 253 |  | -		*heads = ( end_head + 1 );
 | 
		
	
		
			
			| 254 |  | -		*sectors = end_sector;
 | 
		
	
		
			
			| 255 |  | -		DBGC ( sandev, "INT13 drive %02x guessing C/H/S xx/%d/%d based "
 | 
		
	
		
			
			| 256 |  | -		       "on partition %d\n",
 | 
		
	
		
			
			| 257 |  | -		       sandev->drive, *heads, *sectors, ( i + 1 ) );
 | 
		
	
		
			
			|  | 274 | +		if ( ( end_head + 1 ) > *heads ) {
 | 
		
	
		
			
			|  | 275 | +			*heads = ( end_head + 1 );
 | 
		
	
		
			
			|  | 276 | +			DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
 | 
		
	
		
			
			|  | 277 | +			       "xx/%d/xx based on partition %d\n",
 | 
		
	
		
			
			|  | 278 | +			       sandev->drive, *heads, ( i + 1 ) );
 | 
		
	
		
			
			|  | 279 | +		}
 | 
		
	
		
			
			|  | 280 | +		if ( end_sector > *sectors ) {
 | 
		
	
		
			
			|  | 281 | +			*sectors = end_sector;
 | 
		
	
		
			
			|  | 282 | +			DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
 | 
		
	
		
			
			|  | 283 | +			       "xx/xx/%d based on partition %d\n",
 | 
		
	
		
			
			|  | 284 | +			       sandev->drive, *sectors, ( i + 1 ) );
 | 
		
	
		
			
			|  | 285 | +		}
 | 
		
	
		
			
			| 258 | 286 |  	}
 | 
		
	
		
			
			| 259 | 287 |  
 | 
		
	
		
			
			|  | 288 | +	/* Default guess is xx/255/63 */
 | 
		
	
		
			
			|  | 289 | +	if ( ! *heads )
 | 
		
	
		
			
			|  | 290 | +		*heads = 255;
 | 
		
	
		
			
			|  | 291 | +	if ( ! *sectors )
 | 
		
	
		
			
			|  | 292 | +		*sectors = 63;
 | 
		
	
		
			
			|  | 293 | +
 | 
		
	
		
			
			| 260 | 294 |  	return 0;
 | 
		
	
		
			
			| 261 | 295 |  }
 | 
		
	
		
			
			| 262 | 296 |  
 |