Skip to content

Commit

Permalink
ide-disk: workaround for buggy HPA support on ST340823A (take 3)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Aug 20, 2007
1 parent 76e1faa commit b0244a0
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/ide/ide-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id)
&& id->lba_capacity_2;
}

/*
* Some disks report total number of sectors instead of
* maximum sector address. We list them here.
*/
static const struct drive_list_entry hpa_list[] = {
{ "ST340823A", NULL },
{ NULL, NULL }
};

static void idedisk_check_hpa(ide_drive_t *drive)
{
unsigned long long capacity, set_max;
Expand All @@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive)
else
set_max = idedisk_read_native_max_address(drive);

if (ide_in_drive_list(drive->id, hpa_list)) {
/*
* Since we are inclusive wrt to firmware revisions do this
* extra check and apply the workaround only when needed.
*/
if (set_max == capacity + 1)
set_max--;
}

if (set_max <= capacity)
return;

Expand Down
2 changes: 2 additions & 0 deletions drivers/ide/ide-iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv
return 0;
}

EXPORT_SYMBOL_GPL(ide_in_drive_list);

/*
* Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
* We list them here and depend on the device side cable detection for them.
Expand Down

0 comments on commit b0244a0

Please sign in to comment.