Skip to content

Commit c745dfc

Browse files
vonericsenDamien Le Moal
authored andcommitted
libata: fix reading concurrent positioning ranges log
The concurrent positioning ranges log is not a fixed size and may depend on how many ranges are supported by the device. This patch uses the size reported in the GPL directory to determine the number of pages supported by the device before attempting to read this log page. This resolves this error from the dmesg output: ata6.00: Read log 0x47 page 0x00 failed, Emask 0x1 Cc: stable@vger.kernel.org Fixes: fe22e1c ("libata: support concurrent positioning ranges log") Signed-off-by: Tyler Erickson <tyler.erickson@seagate.com> Reviewed-by: Muhammad Ahmad <muhammad.ahmad@seagate.com> Tested-by: Michael English <michael.english@seagate.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
1 parent 10d6bdf commit c745dfc

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

drivers/ata/libata-core.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,16 +2010,16 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
20102010
return err_mask;
20112011
}
20122012

2013-
static bool ata_log_supported(struct ata_device *dev, u8 log)
2013+
static int ata_log_supported(struct ata_device *dev, u8 log)
20142014
{
20152015
struct ata_port *ap = dev->link->ap;
20162016

20172017
if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR)
2018-
return false;
2018+
return 0;
20192019

20202020
if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1))
2021-
return false;
2022-
return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false;
2021+
return 0;
2022+
return get_unaligned_le16(&ap->sector_buf[log * 2]);
20232023
}
20242024

20252025
static bool ata_identify_page_supported(struct ata_device *dev, u8 page)
@@ -2455,15 +2455,20 @@ static void ata_dev_config_cpr(struct ata_device *dev)
24552455
struct ata_cpr_log *cpr_log = NULL;
24562456
u8 *desc, *buf = NULL;
24572457

2458-
if (ata_id_major_version(dev->id) < 11 ||
2459-
!ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES))
2458+
if (ata_id_major_version(dev->id) < 11)
2459+
goto out;
2460+
2461+
buf_len = ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES);
2462+
if (buf_len == 0)
24602463
goto out;
24612464

24622465
/*
24632466
* Read the concurrent positioning ranges log (0x47). We can have at
2464-
* most 255 32B range descriptors plus a 64B header.
2467+
* most 255 32B range descriptors plus a 64B header. This log varies in
2468+
* size, so use the size reported in the GPL directory. Reading beyond
2469+
* the supported length will result in an error.
24652470
*/
2466-
buf_len = (64 + 255 * 32 + 511) & ~511;
2471+
buf_len <<= 9;
24672472
buf = kzalloc(buf_len, GFP_KERNEL);
24682473
if (!buf)
24692474
goto out;

0 commit comments

Comments
 (0)