From 613caa75b7244ef999e0d617587dc456d86b03b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Wadowski?= Date: Thu, 16 May 2019 11:12:59 +0200 Subject: [PATCH] libata: Fix for initialize drives not capable to handle maximum bandwidth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libata-core: sata_down_spd_limit should handle spd values that may not be correct in some cases. libata-eh: ata_eh_reset add check if device is online after reset. If not then it should try to down spd limit and try to reconnect. Signed-off-by: MichaƂ Wadowski --- drivers/ata/libata-core.c | 12 ++++++------ drivers/ata/libata-eh.c | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index adf28788cab5..f3bc1e9c21ee 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3072,6 +3072,11 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) if (mask <= 1) return -EINVAL; + /* sata_spd_limit may by initially INT_MAX, that is not correct value to working with. + * Cut down mask to highest correct value. + */ + mask &= 0x7; + /* unconditionally mask off the highest bit */ bit = fls(mask) - 1; mask &= ~(1 << bit); @@ -3080,15 +3085,10 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) * Mask off all speeds higher than or equal to the current one. At * this point, if current SPD is not available and we previously * recorded the link speed from SStatus, the driver has already - * masked off the highest bit so mask should already be 1 or 0. - * Otherwise, we should not force 1.5Gbps on a link where we have - * not previously recorded speed from SStatus. Just return in this - * case. + * masked off the highest bit. */ if (spd > 1) mask &= (1 << (spd - 1)) - 1; - else - return -EINVAL; /* were we already at the bottom? */ if (!mask) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 938ed513b070..8a0c412796b8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2808,6 +2808,9 @@ int ata_eh_reset(struct ata_link *link, int classify, ehc->i.flags |= ATA_EHI_DID_SOFTRESET; rc = ata_do_reset(link, reset, classes, deadline, true); + if( !rc && ata_link_offline(link) ) + rc = -EPIPE; + if (rc && rc != -EAGAIN) { failed_link = link; goto fail; -- 2.7.4