Skip to content

Commit fda17af

Browse files
author
Damien Le Moal
committed
ata: libata-core: Fix ata_dev_config_cpr()
The concurrent positioning ranges log page 47h is a general purpose log page and not a subpage of the indentify device log. Using ata_identify_page_supported() to test for concurrent positioning ranges support is thus wrong. ata_log_supported() must be used. Furthermore, unlike other advanced ATA features (e.g. NCQ priority), accesses to the concurrent positioning ranges log page are not gated by a feature bit from the device IDENTIFY data. Since many older drives react badly to the READ LOG EXT and/or READ LOG DMA EXT commands isued to read device log pages, avoid problems with older drives by limiting the concurrent positioning ranges support detection to drives implementing at least the ACS-4 ATA standard (major version 11). This additional condition effectively turns ata_dev_config_cpr() into a nop for older drives, avoiding problems in the field. Fixes: fe22e1c ("libata: support concurrent positioning ranges log") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215519 Cc: stable@vger.kernel.org Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Abderraouf Adjal <adjal.arf@gmail.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
1 parent dfd42fa commit fda17af

File tree

2 files changed

+7
-9
lines changed

2 files changed

+7
-9
lines changed

drivers/ata/libata-core.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,23 +2448,21 @@ static void ata_dev_config_cpr(struct ata_device *dev)
24482448
struct ata_cpr_log *cpr_log = NULL;
24492449
u8 *desc, *buf = NULL;
24502450

2451-
if (!ata_identify_page_supported(dev,
2452-
ATA_LOG_CONCURRENT_POSITIONING_RANGES))
2451+
if (ata_id_major_version(dev->id) < 11 ||
2452+
!ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES))
24532453
goto out;
24542454

24552455
/*
2456-
* Read IDENTIFY DEVICE data log, page 0x47
2457-
* (concurrent positioning ranges). We can have at most 255 32B range
2458-
* descriptors plus a 64B header.
2456+
* Read the concurrent positioning ranges log (0x47). We can have at
2457+
* most 255 32B range descriptors plus a 64B header.
24592458
*/
24602459
buf_len = (64 + 255 * 32 + 511) & ~511;
24612460
buf = kzalloc(buf_len, GFP_KERNEL);
24622461
if (!buf)
24632462
goto out;
24642463

2465-
err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE,
2466-
ATA_LOG_CONCURRENT_POSITIONING_RANGES,
2467-
buf, buf_len >> 9);
2464+
err_mask = ata_read_log_page(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES,
2465+
0, buf, buf_len >> 9);
24682466
if (err_mask)
24692467
goto out;
24702468

include/linux/ata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ enum {
324324
ATA_LOG_NCQ_NON_DATA = 0x12,
325325
ATA_LOG_NCQ_SEND_RECV = 0x13,
326326
ATA_LOG_IDENTIFY_DEVICE = 0x30,
327+
ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47,
327328

328329
/* Identify device log pages: */
329330
ATA_LOG_SECURITY = 0x06,
330331
ATA_LOG_SATA_SETTINGS = 0x08,
331332
ATA_LOG_ZONED_INFORMATION = 0x09,
332-
ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47,
333333

334334
/* Identify device SATA settings log:*/
335335
ATA_LOG_DEVSLP_OFFSET = 0x30,

0 commit comments

Comments
 (0)