PATCH: fix bad geometry hang, printing of optional fields

From: Alan Cox
Date: Sun Aug 15 2004 - 09:44:40 EST


If you get invalid geometry (eg a failed drive) the box hangs on boot because
we try and unregister the registered driver and end up in a locking mess.

We change the behaviour to simply leave the device unattached which avoids
the mess.

Also if a drive reports no geometry then don't try and verify the LBA
data is correct against the geometry. Also don't print the non-existant
legacy geometry.


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.8-rc3/drivers/ide/ide-disk.c linux-2.6.8-rc3/drivers/ide/ide-disk.c
--- linux.vanilla-2.6.8-rc3/drivers/ide/ide-disk.c 2004-08-09 15:51:00.000000000 +0100
+++ linux-2.6.8-rc3/drivers/ide/ide-disk.c 2004-08-14 20:37:18.000000000 +0100
@@ -100,7 +100,11 @@
(id->heads == 15 || id->heads == 16) &&
(id->lba_capacity >= 16383*63*id->heads))
return 1;
-
+
+ /* No non LBA info .. so valid! */
+ if (id->heads == 0)
+ return 1;
+
lba_sects = id->lba_capacity;
chs_sects = id->cyls * id->heads * id->sectors;

@@ -1012,7 +1016,9 @@
drive->capacity64 = id->lba_capacity;
if (hpa)
idedisk_check_hpa(drive);
- } else {
+ }
+ else
+ {
/* drive speaks boring old 28-bit CHS */
drive->capacity64 = drive->cyl * drive->head * drive->sect;
}
@@ -1515,8 +1521,8 @@
if (id->buf_size)
printk (" w/%dKiB Cache", id->buf_size/2);

- printk(", CHS=%d/%d/%d",
- drive->bios_cyl, drive->bios_head, drive->bios_sect);
+ if(drive->bios_cyl)
+ printk(", CHS=%d/%d/%d", drive->bios_cyl, drive->bios_head, drive->bios_sect);
if (drive->using_dma)
(void) HWIF(drive)->ide_dma_verbose(drive);
printk("\n");
@@ -1723,11 +1729,10 @@
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
drive->name, drive->head);
- ide_cacheflush_p(drive);
- ide_unregister_subdriver(drive);
- DRIVER(drive)->busy--;
- goto failed;
+ drive->attach = 0;
}
+ else
+ drive->attach = 1;
DRIVER(drive)->busy--;
g->minors = 1 << PARTN_BITS;
strcpy(g->devfs_name, drive->devfs_name);
@@ -1735,7 +1740,6 @@
g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
set_capacity(g, current_capacity(drive));
g->fops = &idedisk_ops;
- drive->attach = 1;
add_disk(g);
return 0;
failed:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/