diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-08-20 16:42:57 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-08-20 16:42:57 -0400 |
commit | b0244a00451c1ad64bf0a51f50679f7146786780 (patch) | |
tree | 14f7725795ba27712a6d76820dde336ad6a17ef8 /drivers | |
parent | 76e1faa7cfd464fa06a9c2cafd633d643daafeae (diff) |
ide-disk: workaround for buggy HPA support on ST340823A (take 3)
This disk reports total number of sectors instead of maximum sector address
in response to READ_NATIVE_MAX_ADDRESS command and also happily accepts
SET_MAX_ADDRESS command with the bogus value. This results in +1 sector
capacity being used and errors on attempts to use the last sector.
...
hdd: Host Protected Area detected.
    current capacity is 78165360 sectors (40020 MB)
    native  capacity is 78165361 sectors (40020 MB)
hdd: Host Protected Area disabled.
...
hdd: reading: block=78165360, sectors=1, buffer=0xc1e63000
hdd: dma_intr: status=0x51 { DriveReady SeekComplete Error }
hdd: dma_intr: error=0x10 { SectorIdNotFound }, LBAsect=78165360, sector=78165360
...
Add hpa_list[] table and workaround the issue in idedisk_check_hpa().
v2:
* Add missing export and improve patch description a bit.
v3:
* Add list termination. (From Mikko)
Fixes kernel bugzilla bug #8816.
Thanks to Mikko for investigating the issue and helping with this patch.
Cc: Mikko Rapeli <mikko.rapeli@iki.fi>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/ide-disk.c | 18 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 2 |
2 files changed, 20 insertions, 0 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5ce4216f72a2..eba1adbc1b6a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) | |||
481 | && id->lba_capacity_2; | 481 | && id->lba_capacity_2; |
482 | } | 482 | } |
483 | 483 | ||
484 | /* | ||
485 | * Some disks report total number of sectors instead of | ||
486 | * maximum sector address. We list them here. | ||
487 | */ | ||
488 | static const struct drive_list_entry hpa_list[] = { | ||
489 | { "ST340823A", NULL }, | ||
490 | { NULL, NULL } | ||
491 | }; | ||
492 | |||
484 | static void idedisk_check_hpa(ide_drive_t *drive) | 493 | static void idedisk_check_hpa(ide_drive_t *drive) |
485 | { | 494 | { |
486 | unsigned long long capacity, set_max; | 495 | unsigned long long capacity, set_max; |
@@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
492 | else | 501 | else |
493 | set_max = idedisk_read_native_max_address(drive); | 502 | set_max = idedisk_read_native_max_address(drive); |
494 | 503 | ||
504 | if (ide_in_drive_list(drive->id, hpa_list)) { | ||
505 | /* | ||
506 | * Since we are inclusive wrt to firmware revisions do this | ||
507 | * extra check and apply the workaround only when needed. | ||
508 | */ | ||
509 | if (set_max == capacity + 1) | ||
510 | set_max--; | ||
511 | } | ||
512 | |||
495 | if (set_max <= capacity) | 513 | if (set_max <= capacity) |
496 | return; | 514 | return; |
497 | 515 | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 18cf3a66a1a3..f4cd2700cae5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -584,6 +584,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv | |||
584 | return 0; | 584 | return 0; |
585 | } | 585 | } |
586 | 586 | ||
587 | EXPORT_SYMBOL_GPL(ide_in_drive_list); | ||
588 | |||
587 | /* | 589 | /* |
588 | * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. | 590 | * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. |
589 | * We list them here and depend on the device side cable detection for them. | 591 | * We list them here and depend on the device side cable detection for them. |