From: Andries.Brouwer@cwi.nl It is already nine months ago that I first had to provide people with a patch that made the boot messages report disk capacity in 32 bits instead of 31. No doubt 2.6 will last long enough to make disk capacity (for RAIDs at least) pass the 2^32 sectors. Probably we should keep track of disk capacities in sector_t instead of long. drivers/ide/ide-cd.c | 2 +- drivers/ide/ide-disk.c | 36 ++++++++++++++++++++++++++---------- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide.c | 4 ++-- include/linux/ide.h | 4 ++-- 5 files changed, 32 insertions(+), 16 deletions(-) diff -puN drivers/ide/ide.c~ide-capacity-fixes drivers/ide/ide.c --- 25/drivers/ide/ide.c~ide-capacity-fixes 2003-08-04 15:20:57.000000000 -0700 +++ 25-akpm/drivers/ide/ide.c 2003-08-04 15:20:57.000000000 -0700 @@ -351,7 +351,7 @@ int ide_system_bus_speed (void) * current_capacity() returns the capacity (in sectors) of a drive * according to its current geometry/LBA settings. */ -unsigned long current_capacity (ide_drive_t *drive) +sector_t current_capacity (ide_drive_t *drive) { if (!drive->present) return 0; @@ -2391,7 +2391,7 @@ static void default_pre_reset (ide_drive { } -static unsigned long default_capacity (ide_drive_t *drive) +static sector_t default_capacity (ide_drive_t *drive) { return 0x7fffffff; } diff -puN drivers/ide/ide-cd.c~ide-capacity-fixes drivers/ide/ide-cd.c --- 25/drivers/ide/ide-cd.c~ide-capacity-fixes 2003-08-04 15:20:57.000000000 -0700 +++ 25-akpm/drivers/ide/ide-cd.c 2003-08-04 15:20:57.000000000 -0700 @@ -3233,7 +3233,7 @@ int ide_cdrom_setup (ide_drive_t *drive) } static -unsigned long ide_cdrom_capacity (ide_drive_t *drive) +sector_t ide_cdrom_capacity (ide_drive_t *drive) { unsigned long capacity; diff -puN drivers/ide/ide-disk.c~ide-capacity-fixes drivers/ide/ide-disk.c --- 25/drivers/ide/ide-disk.c~ide-capacity-fixes 2003-08-04 15:20:57.000000000 -0700 +++ 25-akpm/drivers/ide/ide-disk.c 2003-08-04 15:20:57.000000000 -0700 @@ -1065,6 +1065,13 @@ static unsigned long long idedisk_set_ma #endif /* CONFIG_IDEDISK_STROKE */ +static unsigned long long +sectors_to_MB(unsigned long long n) { + n <<= 9; /* make it bytes */ + do_div(n, 1000000); /* make it MB */ + return n; +} + /* * Tests if the drive supports Host Protected Area feature. * Returns true if supported, false otherwise. @@ -1165,7 +1172,7 @@ static void init_idedisk_capacity (ide_d } } -static unsigned long idedisk_capacity (ide_drive_t *drive) +static sector_t idedisk_capacity (ide_drive_t *drive) { if (drive->id->cfs_enable_2 & 0x0400) return (drive->capacity48 - drive->sect0); @@ -1564,7 +1571,7 @@ static ide_startstop_t idedisk_start_pow static void idedisk_setup (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - unsigned long capacity; + unsigned long long capacity; idedisk_add_settings(drive); @@ -1628,14 +1635,23 @@ static void idedisk_setup (ide_drive_t * * by correcting bios_cyls: */ capacity = idedisk_capacity (drive); - if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) && - (!drive->forced_geom) && drive->bios_sect && drive->bios_head) - drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head; - printk (KERN_INFO "%s: %ld sectors", drive->name, capacity); - - /* Give size in megabytes (MB), not mebibytes (MiB). */ - /* We compute the exact rounded value, avoiding overflow. */ - printk (" (%ld MB)", (capacity - capacity/625 + 974)/1950); + if (!drive->forced_geom && drive->bios_sect && drive->bios_head) { + unsigned int cap0 = capacity; /* truncate to 32 bits */ + unsigned int cylsz, cyl; + + if (cap0 != capacity) + drive->bios_cyl = 65535; + else { + cylsz = drive->bios_sect * drive->bios_head; + cyl = cap0 / cylsz; + if (cyl > 65535) + cyl = 65535; + if (cyl > drive->bios_cyl) + drive->bios_cyl = cyl; + } + } + printk(KERN_INFO "%s: %llu sectors (%llu MB)", + drive->name, capacity, sectors_to_MB(capacity)); /* Only print cache size when it was specified */ if (id->buf_size) diff -puN drivers/ide/ide-floppy.c~ide-capacity-fixes drivers/ide/ide-floppy.c --- 25/drivers/ide/ide-floppy.c~ide-capacity-fixes 2003-08-04 15:20:57.000000000 -0700 +++ 25-akpm/drivers/ide/ide-floppy.c 2003-08-04 15:20:57.000000000 -0700 @@ -1626,7 +1626,7 @@ static int idefloppy_get_format_progress /* * Return the current floppy capacity to ide.c. */ -static unsigned long idefloppy_capacity (ide_drive_t *drive) +static sector_t idefloppy_capacity (ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; unsigned long capacity = floppy->blocks * floppy->bs_factor; diff -puN include/linux/ide.h~ide-capacity-fixes include/linux/ide.h --- 25/include/linux/ide.h~ide-capacity-fixes 2003-08-04 15:20:57.000000000 -0700 +++ 25-akpm/include/linux/ide.h 2003-08-04 15:20:57.000000000 -0700 @@ -1225,7 +1225,7 @@ typedef struct ide_driver_s { ide_startstop_t (*abort)(ide_drive_t *, const char *); int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); void (*pre_reset)(ide_drive_t *); - unsigned long (*capacity)(ide_drive_t *); + sector_t (*capacity)(ide_drive_t *); ide_startstop_t (*special)(ide_drive_t *); ide_proc_entry_t *proc; int (*attach)(ide_drive_t *); @@ -1358,7 +1358,7 @@ extern int ide_wait_stat(ide_startstop_t /* * Return the current idea about the total capacity of this drive. */ -extern unsigned long current_capacity (ide_drive_t *drive); +extern sector_t current_capacity (ide_drive_t *drive); /* * Start a reset operation for an IDE interface. _