2019-05-19 13:51:48 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2006-04-02 09:51:53 +00:00
|
|
|
/*
|
|
|
|
* libata-eh.c - libata error handling
|
|
|
|
*
|
|
|
|
* Copyright 2006 Tejun Heo <htejun@gmail.com>
|
|
|
|
*
|
|
|
|
* libata documentation is available via 'make {ps|pdf}docs',
|
2017-05-16 12:16:37 +00:00
|
|
|
* as Documentation/driver-api/libata.rst
|
2006-04-02 09:51:53 +00:00
|
|
|
*
|
|
|
|
* Hardware documentation available from http://www.t13.org/ and
|
|
|
|
* http://www.sata-io.org/
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
2008-09-14 12:55:09 +00:00
|
|
|
#include <linux/blkdev.h>
|
2011-07-17 19:33:58 +00:00
|
|
|
#include <linux/export.h>
|
2007-10-11 21:12:35 +00:00
|
|
|
#include <linux/pci.h>
|
2006-04-02 09:51:53 +00:00
|
|
|
#include <scsi/scsi.h>
|
|
|
|
#include <scsi/scsi_host.h>
|
|
|
|
#include <scsi/scsi_eh.h>
|
|
|
|
#include <scsi/scsi_device.h>
|
|
|
|
#include <scsi/scsi_cmnd.h>
|
2009-07-15 02:43:39 +00:00
|
|
|
#include <scsi/scsi_dbg.h>
|
2006-08-10 11:31:37 +00:00
|
|
|
#include "../scsi/scsi_transport_api.h"
|
2006-04-02 09:51:53 +00:00
|
|
|
|
|
|
|
#include <linux/libata.h>
|
|
|
|
|
2015-03-27 15:46:38 +00:00
|
|
|
#include <trace/events/libata.h>
|
2006-04-02 09:51:53 +00:00
|
|
|
#include "libata.h"
|
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
enum {
|
2007-11-27 10:28:56 +00:00
|
|
|
/* speed down verdicts */
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
ATA_EH_SPDN_NCQ_OFF = (1 << 0),
|
|
|
|
ATA_EH_SPDN_SPEED_DOWN = (1 << 1),
|
|
|
|
ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2),
|
2007-11-27 10:28:59 +00:00
|
|
|
ATA_EH_SPDN_KEEP_ERRORS = (1 << 3),
|
2007-11-27 10:28:56 +00:00
|
|
|
|
|
|
|
/* error flags */
|
|
|
|
ATA_EFLAG_IS_IO = (1 << 0),
|
2007-11-27 10:28:59 +00:00
|
|
|
ATA_EFLAG_DUBIOUS_XFER = (1 << 1),
|
2010-05-25 19:31:38 +00:00
|
|
|
ATA_EFLAG_OLD_ER = (1 << 31),
|
2007-11-27 10:28:56 +00:00
|
|
|
|
|
|
|
/* error categories */
|
|
|
|
ATA_ECAT_NONE = 0,
|
|
|
|
ATA_ECAT_ATA_BUS = 1,
|
|
|
|
ATA_ECAT_TOUT_HSM = 2,
|
|
|
|
ATA_ECAT_UNK_DEV = 3,
|
2008-01-02 16:21:14 +00:00
|
|
|
ATA_ECAT_DUBIOUS_NONE = 4,
|
|
|
|
ATA_ECAT_DUBIOUS_ATA_BUS = 5,
|
|
|
|
ATA_ECAT_DUBIOUS_TOUT_HSM = 6,
|
|
|
|
ATA_ECAT_DUBIOUS_UNK_DEV = 7,
|
|
|
|
ATA_ECAT_NR = 8,
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
|
2008-05-19 17:17:54 +00:00
|
|
|
ATA_EH_CMD_DFL_TIMEOUT = 5000,
|
|
|
|
|
2008-05-19 17:17:52 +00:00
|
|
|
/* always put at least this amount of time between resets */
|
|
|
|
ATA_EH_RESET_COOL_DOWN = 5000,
|
|
|
|
|
2008-05-19 17:17:51 +00:00
|
|
|
/* Waiting in ->prereset can never be reliable. It's
|
|
|
|
* sometimes nice to wait there but it can't be depended upon;
|
|
|
|
* otherwise, we wouldn't be resetting. Just give it enough
|
|
|
|
* time for most drives to spin up.
|
|
|
|
*/
|
|
|
|
ATA_EH_PRERESET_TIMEOUT = 10000,
|
|
|
|
ATA_EH_FASTDRAIN_INTERVAL = 3000,
|
2008-08-30 12:20:01 +00:00
|
|
|
|
|
|
|
ATA_EH_UA_TRIES = 5,
|
2009-01-29 11:31:34 +00:00
|
|
|
|
|
|
|
/* probe speed down parameters, see ata_eh_schedule_probe() */
|
|
|
|
ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */
|
|
|
|
ATA_EH_PROBE_TRIALS = 2,
|
2007-02-02 07:50:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* The following table determines how we sequence resets. Each entry
|
|
|
|
* represents timeout for that try. The first try can be soft or
|
|
|
|
* hardreset. All others are hardreset if available. In most cases
|
|
|
|
* the first reset w/ 10sec timeout should succeed. Following entries
|
2014-03-07 22:22:48 +00:00
|
|
|
* are mostly for error handling, hotplug and those outlier devices that
|
|
|
|
* take an exceptionally long time to recover from reset.
|
2007-02-02 07:50:52 +00:00
|
|
|
*/
|
2023-07-29 20:17:48 +00:00
|
|
|
static const unsigned int ata_eh_reset_timeouts[] = {
|
2008-05-19 17:17:51 +00:00
|
|
|
10000, /* most drives spin up by 10sec */
|
|
|
|
10000, /* > 99% working drives spin up before 20sec */
|
2014-03-07 22:22:48 +00:00
|
|
|
35000, /* give > 30 secs of idleness for outlier devices */
|
2008-05-19 17:17:51 +00:00
|
|
|
5000, /* and sweet one last chance */
|
2023-07-29 20:17:48 +00:00
|
|
|
UINT_MAX, /* > 1 min has elapsed, give up */
|
2007-02-02 07:50:52 +00:00
|
|
|
};
|
|
|
|
|
2022-06-18 20:38:10 +00:00
|
|
|
static const unsigned int ata_eh_identify_timeouts[] = {
|
2008-05-19 17:17:54 +00:00
|
|
|
5000, /* covers > 99% of successes and not too boring on failures */
|
|
|
|
10000, /* combined time till here is enough even for media access */
|
|
|
|
30000, /* for true idiots */
|
2022-06-18 20:38:10 +00:00
|
|
|
UINT_MAX,
|
2008-05-19 17:17:54 +00:00
|
|
|
};
|
|
|
|
|
2022-06-18 20:38:10 +00:00
|
|
|
static const unsigned int ata_eh_revalidate_timeouts[] = {
|
libata: fix read log timeout value
Some ATA drives are very slow to respond to READ_LOG_EXT and
READ_LOG_DMA_EXT commands issued from ata_dev_configure() when the
device is revalidated right after resuming a system or inserting the
ATA adapter driver (e.g. ahci). The default 5s timeout
(ATA_EH_CMD_DFL_TIMEOUT) used for these commands is too short, causing
errors during the device configuration. Ex:
...
ata9: SATA max UDMA/133 abar m524288@0x9d200000 port 0x9d200400 irq 209
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: ATA-9: XXX XXXXXXXXXXXXXXX, XXXXXXXX, max UDMA/133
ata9.00: qc timeout (cmd 0x2f)
ata9.00: Read log page 0x00 failed, Emask 0x4
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: NCQ Send/Recv Log not supported
ata9.00: Read log page 0x08 failed, Emask 0x40
ata9.00: 27344764928 sectors, multi 16: LBA48 NCQ (depth 32), AA
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: ATA Identify Device Log not supported
ata9.00: failed to set xfermode (err_mask=0x40)
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: configured for UDMA/133
...
The timeout error causes a soft reset of the drive link, followed in
most cases by a successful revalidation as that give enough time to the
drive to become fully ready to quickly process the read log commands.
However, in some cases, this also fails resulting in the device being
dropped.
Fix this by using adding the ata_eh_revalidate_timeouts entries for the
READ_LOG_EXT and READ_LOG_DMA_EXT commands. This defines a timeout
increased to 15s, retriable one time.
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2021-11-04 08:31:58 +00:00
|
|
|
15000, /* Some drives are slow to read log pages when waking-up */
|
|
|
|
15000, /* combined time till here is enough even for media access */
|
2022-06-18 20:38:10 +00:00
|
|
|
UINT_MAX,
|
libata: fix read log timeout value
Some ATA drives are very slow to respond to READ_LOG_EXT and
READ_LOG_DMA_EXT commands issued from ata_dev_configure() when the
device is revalidated right after resuming a system or inserting the
ATA adapter driver (e.g. ahci). The default 5s timeout
(ATA_EH_CMD_DFL_TIMEOUT) used for these commands is too short, causing
errors during the device configuration. Ex:
...
ata9: SATA max UDMA/133 abar m524288@0x9d200000 port 0x9d200400 irq 209
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: ATA-9: XXX XXXXXXXXXXXXXXX, XXXXXXXX, max UDMA/133
ata9.00: qc timeout (cmd 0x2f)
ata9.00: Read log page 0x00 failed, Emask 0x4
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: NCQ Send/Recv Log not supported
ata9.00: Read log page 0x08 failed, Emask 0x40
ata9.00: 27344764928 sectors, multi 16: LBA48 NCQ (depth 32), AA
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: ATA Identify Device Log not supported
ata9.00: failed to set xfermode (err_mask=0x40)
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: configured for UDMA/133
...
The timeout error causes a soft reset of the drive link, followed in
most cases by a successful revalidation as that give enough time to the
drive to become fully ready to quickly process the read log commands.
However, in some cases, this also fails resulting in the device being
dropped.
Fix this by using adding the ata_eh_revalidate_timeouts entries for the
READ_LOG_EXT and READ_LOG_DMA_EXT commands. This defines a timeout
increased to 15s, retriable one time.
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2021-11-04 08:31:58 +00:00
|
|
|
};
|
|
|
|
|
2022-06-18 20:38:10 +00:00
|
|
|
static const unsigned int ata_eh_flush_timeouts[] = {
|
2009-11-19 06:36:45 +00:00
|
|
|
15000, /* be generous with flush */
|
|
|
|
15000, /* ditto */
|
|
|
|
30000, /* and even more generous */
|
2022-06-18 20:38:10 +00:00
|
|
|
UINT_MAX,
|
2009-11-19 06:36:45 +00:00
|
|
|
};
|
|
|
|
|
2022-06-18 20:38:10 +00:00
|
|
|
static const unsigned int ata_eh_other_timeouts[] = {
|
2008-05-19 17:17:54 +00:00
|
|
|
5000, /* same rationale as identify timeout */
|
|
|
|
10000, /* ditto */
|
|
|
|
/* but no merciful 30sec for other commands, it just isn't worth it */
|
2022-06-18 20:38:10 +00:00
|
|
|
UINT_MAX,
|
2008-05-19 17:17:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ata_eh_cmd_timeout_ent {
|
|
|
|
const u8 *commands;
|
2022-06-18 20:38:10 +00:00
|
|
|
const unsigned int *timeouts;
|
2008-05-19 17:17:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* The following table determines timeouts to use for EH internal
|
|
|
|
* commands. Each table entry is a command class and matches the
|
|
|
|
* commands the entry applies to and the timeout table to use.
|
|
|
|
*
|
|
|
|
* On the retry after a command timed out, the next timeout value from
|
|
|
|
* the table is used. If the table doesn't contain further entries,
|
|
|
|
* the last value is used.
|
|
|
|
*
|
|
|
|
* ehc->cmd_timeout_idx keeps track of which timeout to use per
|
|
|
|
* command class, so if SET_FEATURES times out on the first try, the
|
|
|
|
* next try will use the second timeout value only for that class.
|
|
|
|
*/
|
|
|
|
#define CMDS(cmds...) (const u8 []){ cmds, 0 }
|
|
|
|
static const struct ata_eh_cmd_timeout_ent
|
|
|
|
ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = {
|
|
|
|
{ .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI),
|
|
|
|
.timeouts = ata_eh_identify_timeouts, },
|
libata: fix read log timeout value
Some ATA drives are very slow to respond to READ_LOG_EXT and
READ_LOG_DMA_EXT commands issued from ata_dev_configure() when the
device is revalidated right after resuming a system or inserting the
ATA adapter driver (e.g. ahci). The default 5s timeout
(ATA_EH_CMD_DFL_TIMEOUT) used for these commands is too short, causing
errors during the device configuration. Ex:
...
ata9: SATA max UDMA/133 abar m524288@0x9d200000 port 0x9d200400 irq 209
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: ATA-9: XXX XXXXXXXXXXXXXXX, XXXXXXXX, max UDMA/133
ata9.00: qc timeout (cmd 0x2f)
ata9.00: Read log page 0x00 failed, Emask 0x4
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: NCQ Send/Recv Log not supported
ata9.00: Read log page 0x08 failed, Emask 0x40
ata9.00: 27344764928 sectors, multi 16: LBA48 NCQ (depth 32), AA
ata9.00: Read log page 0x00 failed, Emask 0x40
ata9.00: ATA Identify Device Log not supported
ata9.00: failed to set xfermode (err_mask=0x40)
ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ata9.00: configured for UDMA/133
...
The timeout error causes a soft reset of the drive link, followed in
most cases by a successful revalidation as that give enough time to the
drive to become fully ready to quickly process the read log commands.
However, in some cases, this also fails resulting in the device being
dropped.
Fix this by using adding the ata_eh_revalidate_timeouts entries for the
READ_LOG_EXT and READ_LOG_DMA_EXT commands. This defines a timeout
increased to 15s, retriable one time.
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2021-11-04 08:31:58 +00:00
|
|
|
{ .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT),
|
|
|
|
.timeouts = ata_eh_revalidate_timeouts, },
|
2008-05-19 17:17:54 +00:00
|
|
|
{ .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT),
|
|
|
|
.timeouts = ata_eh_other_timeouts, },
|
|
|
|
{ .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT),
|
|
|
|
.timeouts = ata_eh_other_timeouts, },
|
|
|
|
{ .commands = CMDS(ATA_CMD_SET_FEATURES),
|
|
|
|
.timeouts = ata_eh_other_timeouts, },
|
|
|
|
{ .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS),
|
|
|
|
.timeouts = ata_eh_other_timeouts, },
|
2009-11-19 06:36:45 +00:00
|
|
|
{ .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT),
|
|
|
|
.timeouts = ata_eh_flush_timeouts },
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
{ .commands = CMDS(ATA_CMD_VERIFY),
|
|
|
|
.timeouts = ata_eh_reset_timeouts },
|
2008-05-19 17:17:54 +00:00
|
|
|
};
|
|
|
|
#undef CMDS
|
|
|
|
|
2006-05-15 11:58:12 +00:00
|
|
|
static void __ata_port_freeze(struct ata_port *ap);
|
ata: libata-eh: avoid needless hard reset when revalidating link
Performing a revalidation on a AHCI controller supporting LPM,
while using a lpm mode of e.g. med_power_with_dip (hipm + dipm) or
medium_power (hipm), will currently always lead to a hard reset.
The expected behavior is that a hard reset is only performed when
revalidate fails, because the properties of the drive has changed.
A revalidate performed after e.g. a NCQ error, or such a simple thing
as disabling write-caching (hdparm -W 0 /dev/sda), should succeed on
the first try (and should therefore not cause the link to be reset).
This unwarranted hard reset happens because ata_phys_link_offline()
returns true for a link that is in deep sleep. Thus the call to
ata_phys_link_offline() in ata_eh_revalidate_and_attach() will cause
the revalidation to fail, which causes ata_eh_handle_dev_fail() to be
called, which will set ehc->i.action |= ATA_EH_RESET, such that the
link is reset before retrying revalidation.
When the link is reset, the link is reestablished, so when
ata_eh_revalidate_and_attach() is called the second time, directly
after the link has been reset, ata_phys_link_offline() will return
false, and the revalidation will succeed.
Looking at "8.3.1.3 HBA Initiated" in the AHCI 1.3.1 specification,
it is clear the when host software writes a new command to memory,
by setting a bit in the PxCI/PxSACT HBA port registers, the HBA will
automatically bring back the link before sending out the Command FIS.
However, simply reading a SCR (like ata_phys_link_offline() does),
will not cause the HBA to automatically bring back the link.
As long as hipm is enabled, the HBA will put an idle link into deep
sleep. Avoid this needless hard reset on revalidation by temporarily
disabling hipm, by setting the LPM mode to ATA_LPM_MAX_POWER.
After revalidation is complete, ata_eh_recover() will restore the link
policy by setting the LPM mode to ap->target_lpm_policy.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-09-21 15:57:52 +00:00
|
|
|
static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|
|
|
struct ata_device **r_failed_dev);
|
2007-03-02 08:32:47 +00:00
|
|
|
#ifdef CONFIG_PM
|
2006-07-03 07:07:27 +00:00
|
|
|
static void ata_eh_handle_port_suspend(struct ata_port *ap);
|
|
|
|
static void ata_eh_handle_port_resume(struct ata_port *ap);
|
2007-03-02 08:32:47 +00:00
|
|
|
#else /* CONFIG_PM */
|
|
|
|
static void ata_eh_handle_port_suspend(struct ata_port *ap)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
static void ata_eh_handle_port_resume(struct ata_port *ap)
|
|
|
|
{ }
|
|
|
|
#endif /* CONFIG_PM */
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2018-05-05 20:00:37 +00:00
|
|
|
static __printf(2, 0) void __ata_ehi_pushv_desc(struct ata_eh_info *ehi,
|
|
|
|
const char *fmt, va_list args)
|
2007-07-16 05:29:39 +00:00
|
|
|
{
|
|
|
|
ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
|
|
|
|
ATA_EH_DESC_LEN - ehi->desc_len,
|
|
|
|
fmt, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* __ata_ehi_push_desc - push error description without adding separator
|
|
|
|
* @ehi: target EHI
|
|
|
|
* @fmt: printf format string
|
|
|
|
*
|
|
|
|
* Format string according to @fmt and append it to @ehi->desc.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
__ata_ehi_pushv_desc(ehi, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
|
2007-07-16 05:29:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_ehi_push_desc - push error description with separator
|
|
|
|
* @ehi: target EHI
|
|
|
|
* @fmt: printf format string
|
|
|
|
*
|
|
|
|
* Format string according to @fmt and append it to @ehi->desc.
|
|
|
|
* If @ehi->desc is not empty, ", " is added in-between.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
if (ehi->desc_len)
|
|
|
|
__ata_ehi_push_desc(ehi, ", ");
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
__ata_ehi_pushv_desc(ehi, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
|
2007-07-16 05:29:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_ehi_clear_desc - clean error description
|
|
|
|
* @ehi: target EHI
|
|
|
|
*
|
|
|
|
* Clear @ehi->desc.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
void ata_ehi_clear_desc(struct ata_eh_info *ehi)
|
|
|
|
{
|
|
|
|
ehi->desc[0] = '\0';
|
|
|
|
ehi->desc_len = 0;
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
|
2007-07-16 05:29:39 +00:00
|
|
|
|
2007-08-18 04:14:55 +00:00
|
|
|
/**
|
|
|
|
* ata_port_desc - append port description
|
|
|
|
* @ap: target ATA port
|
|
|
|
* @fmt: printf format string
|
|
|
|
*
|
|
|
|
* Format string according to @fmt and append it to port
|
|
|
|
* description. If port description is not empty, " " is added
|
|
|
|
* in-between. This function is to be used while initializing
|
|
|
|
* ata_host. The description is printed on host registration.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
|
|
|
void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING));
|
|
|
|
|
|
|
|
if (ap->link.eh_info.desc_len)
|
|
|
|
__ata_ehi_push_desc(&ap->link.eh_info, " ");
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
__ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_desc);
|
2007-08-18 04:14:55 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_PCI
|
|
|
|
/**
|
|
|
|
* ata_port_pbar_desc - append PCI BAR description
|
|
|
|
* @ap: target ATA port
|
|
|
|
* @bar: target PCI BAR
|
|
|
|
* @offset: offset into PCI BAR
|
|
|
|
* @name: name of the area
|
|
|
|
*
|
|
|
|
* If @offset is negative, this function formats a string which
|
|
|
|
* contains the name, address, size and type of the BAR and
|
|
|
|
* appends it to the port description. If @offset is zero or
|
|
|
|
* positive, only name and offsetted address is appended.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
|
|
|
void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
|
|
|
char *type = "";
|
|
|
|
unsigned long long start, len;
|
|
|
|
|
|
|
|
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
|
|
|
|
type = "m";
|
|
|
|
else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
|
|
|
|
type = "i";
|
|
|
|
|
|
|
|
start = (unsigned long long)pci_resource_start(pdev, bar);
|
|
|
|
len = (unsigned long long)pci_resource_len(pdev, bar);
|
|
|
|
|
|
|
|
if (offset < 0)
|
|
|
|
ata_port_desc(ap, "%s %s%llu@0x%llx", name, type, len, start);
|
|
|
|
else
|
2007-12-14 00:01:37 +00:00
|
|
|
ata_port_desc(ap, "%s 0x%llx", name,
|
|
|
|
start + (unsigned long long)offset);
|
2007-08-18 04:14:55 +00:00
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
|
2007-08-18 04:14:55 +00:00
|
|
|
#endif /* CONFIG_PCI */
|
|
|
|
|
2008-05-19 17:17:54 +00:00
|
|
|
static int ata_lookup_timeout_table(u8 cmd)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ATA_EH_CMD_TIMEOUT_TABLE_SIZE; i++) {
|
|
|
|
const u8 *cur;
|
|
|
|
|
|
|
|
for (cur = ata_eh_cmd_timeout_table[i].commands; *cur; cur++)
|
|
|
|
if (*cur == cmd)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_internal_cmd_timeout - determine timeout for an internal command
|
|
|
|
* @dev: target device
|
|
|
|
* @cmd: internal command to be issued
|
|
|
|
*
|
|
|
|
* Determine timeout for internal command @cmd for @dev.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Determined timeout.
|
|
|
|
*/
|
2022-06-18 20:38:10 +00:00
|
|
|
unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd)
|
2008-05-19 17:17:54 +00:00
|
|
|
{
|
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
|
|
|
int ent = ata_lookup_timeout_table(cmd);
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (ent < 0)
|
|
|
|
return ATA_EH_CMD_DFL_TIMEOUT;
|
|
|
|
|
|
|
|
idx = ehc->cmd_timeout_idx[dev->devno][ent];
|
|
|
|
return ata_eh_cmd_timeout_table[ent].timeouts[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_internal_cmd_timed_out - notification for internal command timeout
|
|
|
|
* @dev: target device
|
|
|
|
* @cmd: internal command which timed out
|
|
|
|
*
|
|
|
|
* Notify EH that internal command @cmd for @dev timed out. This
|
|
|
|
* function should be called only for commands whose timeouts are
|
|
|
|
* determined using ata_internal_cmd_timeout().
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context.
|
|
|
|
*/
|
|
|
|
void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd)
|
|
|
|
{
|
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
|
|
|
int ent = ata_lookup_timeout_table(cmd);
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (ent < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
idx = ehc->cmd_timeout_idx[dev->devno][ent];
|
2022-06-18 20:38:10 +00:00
|
|
|
if (ata_eh_cmd_timeout_table[ent].timeouts[idx + 1] != UINT_MAX)
|
2008-05-19 17:17:54 +00:00
|
|
|
ehc->cmd_timeout_idx[dev->devno][ent]++;
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
static void ata_ering_record(struct ata_ering *ering, unsigned int eflags,
|
2006-05-15 11:58:19 +00:00
|
|
|
unsigned int err_mask)
|
|
|
|
{
|
|
|
|
struct ata_ering_entry *ent;
|
|
|
|
|
|
|
|
WARN_ON(!err_mask);
|
|
|
|
|
|
|
|
ering->cursor++;
|
|
|
|
ering->cursor %= ATA_ERING_SIZE;
|
|
|
|
|
|
|
|
ent = &ering->ring[ering->cursor];
|
2007-11-27 10:28:56 +00:00
|
|
|
ent->eflags = eflags;
|
2006-05-15 11:58:19 +00:00
|
|
|
ent->err_mask = err_mask;
|
|
|
|
ent->timestamp = get_jiffies_64();
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering)
|
|
|
|
{
|
|
|
|
struct ata_ering_entry *ent = &ering->ring[ering->cursor];
|
|
|
|
|
|
|
|
if (ent->err_mask)
|
|
|
|
return ent;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-05-25 19:31:38 +00:00
|
|
|
int ata_ering_map(struct ata_ering *ering,
|
|
|
|
int (*map_fn)(struct ata_ering_entry *, void *),
|
|
|
|
void *arg)
|
2006-05-15 11:58:19 +00:00
|
|
|
{
|
|
|
|
int idx, rc = 0;
|
|
|
|
struct ata_ering_entry *ent;
|
|
|
|
|
|
|
|
idx = ering->cursor;
|
|
|
|
do {
|
|
|
|
ent = &ering->ring[idx];
|
|
|
|
if (!ent->err_mask)
|
|
|
|
break;
|
|
|
|
rc = map_fn(ent, arg);
|
|
|
|
if (rc)
|
|
|
|
break;
|
|
|
|
idx = (idx - 1 + ATA_ERING_SIZE) % ATA_ERING_SIZE;
|
|
|
|
} while (idx != ering->cursor);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2012-04-12 22:40:37 +00:00
|
|
|
static int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg)
|
2010-05-25 19:31:38 +00:00
|
|
|
{
|
|
|
|
ent->eflags |= ATA_EFLAG_OLD_ER;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ata_ering_clear(struct ata_ering *ering)
|
|
|
|
{
|
|
|
|
ata_ering_map(ering, ata_ering_clear_cb, NULL);
|
|
|
|
}
|
|
|
|
|
2006-06-24 11:30:18 +00:00
|
|
|
static unsigned int ata_eh_dev_action(struct ata_device *dev)
|
|
|
|
{
|
2007-08-06 09:36:22 +00:00
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
2006-06-24 11:30:18 +00:00
|
|
|
|
|
|
|
return ehc->i.action | ehc->i.dev_action[dev->devno];
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
|
2006-06-24 11:30:18 +00:00
|
|
|
struct ata_eh_info *ehi, unsigned int action)
|
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *tdev;
|
2006-06-24 11:30:18 +00:00
|
|
|
|
|
|
|
if (!dev) {
|
|
|
|
ehi->action &= ~action;
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(tdev, link, ALL)
|
2007-08-06 09:36:23 +00:00
|
|
|
ehi->dev_action[tdev->devno] &= ~action;
|
2006-06-24 11:30:18 +00:00
|
|
|
} else {
|
|
|
|
/* doesn't make sense for port-wide EH actions */
|
|
|
|
WARN_ON(!(action & ATA_EH_PERDEV_MASK));
|
|
|
|
|
|
|
|
/* break ehi->action into ehi->dev_action */
|
|
|
|
if (ehi->action & action) {
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(tdev, link, ALL)
|
2007-08-06 09:36:23 +00:00
|
|
|
ehi->dev_action[tdev->devno] |=
|
|
|
|
ehi->action & action;
|
2006-06-24 11:30:18 +00:00
|
|
|
ehi->action &= ~action;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* turn off the specified per-dev action */
|
|
|
|
ehi->dev_action[dev->devno] &= ~action;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_acquire - acquire EH ownership
|
|
|
|
* @ap: ATA port to acquire EH ownership for
|
|
|
|
*
|
|
|
|
* Acquire EH ownership for @ap. This is the basic exclusion
|
|
|
|
* mechanism for ports sharing a host. Only one port hanging off
|
|
|
|
* the same host can claim the ownership of EH.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context.
|
|
|
|
*/
|
|
|
|
void ata_eh_acquire(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
mutex_lock(&ap->host->eh_mutex);
|
|
|
|
WARN_ON_ONCE(ap->host->eh_owner);
|
|
|
|
ap->host->eh_owner = current;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_release - release EH ownership
|
|
|
|
* @ap: ATA port to release EH ownership for
|
|
|
|
*
|
|
|
|
* Release EH ownership for @ap if the caller. The caller must
|
|
|
|
* have acquired EH ownership using ata_eh_acquire() previously.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context.
|
|
|
|
*/
|
|
|
|
void ata_eh_release(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
WARN_ON_ONCE(ap->host->eh_owner != current);
|
|
|
|
ap->host->eh_owner = NULL;
|
|
|
|
mutex_unlock(&ap->host->eh_mutex);
|
|
|
|
}
|
|
|
|
|
2008-11-03 11:04:37 +00:00
|
|
|
static void ata_eh_unload(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
struct ata_link *link;
|
|
|
|
struct ata_device *dev;
|
|
|
|
unsigned long flags;
|
|
|
|
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
/*
|
|
|
|
* Unless we are restarting, transition all enabled devices to
|
|
|
|
* standby power mode.
|
|
|
|
*/
|
|
|
|
if (system_state != SYSTEM_RESTART) {
|
|
|
|
ata_for_each_link(link, ap, PMP_FIRST) {
|
|
|
|
ata_for_each_dev(dev, link, ENABLED)
|
|
|
|
ata_dev_power_set_standby(dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Restore SControl IPM and SPD for the next driver and
|
2008-11-03 11:04:37 +00:00
|
|
|
* disable attached devices.
|
|
|
|
*/
|
|
|
|
ata_for_each_link(link, ap, PMP_FIRST) {
|
|
|
|
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
|
|
|
|
ata_for_each_dev(dev, link, ALL)
|
|
|
|
ata_dev_disable(dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* freeze and set UNLOADED */
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
|
|
|
|
ata_port_freeze(ap); /* won't be thawed */
|
|
|
|
ap->pflags &= ~ATA_PFLAG_EH_PENDING; /* clear pending from freeze */
|
|
|
|
ap->pflags |= ATA_PFLAG_UNLOADED;
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
}
|
|
|
|
|
2006-04-02 09:51:53 +00:00
|
|
|
/**
|
|
|
|
* ata_scsi_error - SCSI layer error handler callback
|
|
|
|
* @host: SCSI host on which error occurred
|
|
|
|
*
|
|
|
|
* Handles SCSI-layer-thrown error events.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Inherited from SCSI layer (none, can sleep)
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Zero.
|
|
|
|
*/
|
2006-04-11 17:04:39 +00:00
|
|
|
void ata_scsi_error(struct Scsi_Host *host)
|
2006-04-02 09:51:53 +00:00
|
|
|
{
|
2006-04-11 17:12:34 +00:00
|
|
|
struct ata_port *ap = ata_shost_to_port(host);
|
2006-05-15 11:58:12 +00:00
|
|
|
unsigned long flags;
|
2011-01-23 14:31:14 +00:00
|
|
|
LIST_HEAD(eh_work_q);
|
2006-04-02 09:51:53 +00:00
|
|
|
|
2011-01-23 14:31:14 +00:00
|
|
|
spin_lock_irqsave(host->host_lock, flags);
|
|
|
|
list_splice_init(&host->eh_cmd_q, &eh_work_q);
|
|
|
|
spin_unlock_irqrestore(host->host_lock, flags);
|
|
|
|
|
2011-01-23 15:42:50 +00:00
|
|
|
ata_scsi_cmd_error_handler(host, ap, &eh_work_q);
|
|
|
|
|
|
|
|
/* If we timed raced normal completion and there is nothing to
|
|
|
|
recover nr_timedout == 0 why exactly are we doing error recovery ? */
|
|
|
|
ata_scsi_port_error_handler(host, ap);
|
|
|
|
|
|
|
|
/* finish or retry handled scmd's and clean up */
|
2016-06-07 06:53:56 +00:00
|
|
|
WARN_ON(!list_empty(&eh_work_q));
|
2011-01-23 15:42:50 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_scsi_cmd_error_handler - error callback for a list of commands
|
|
|
|
* @host: scsi host containing the port
|
|
|
|
* @ap: ATA port within the host
|
|
|
|
* @eh_work_q: list of commands to process
|
|
|
|
*
|
|
|
|
* process the given list of commands and return those finished to the
|
|
|
|
* ap->eh_done_q. This function is the first part of the libata error
|
|
|
|
* handler which processes a given list of failed commands.
|
|
|
|
*/
|
|
|
|
void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
|
|
|
|
struct list_head *eh_work_q)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned long flags;
|
2022-12-15 15:37:49 +00:00
|
|
|
struct scsi_cmnd *scmd, *tmp;
|
|
|
|
int nr_timedout = 0;
|
2011-01-23 15:42:50 +00:00
|
|
|
|
2010-05-10 19:41:38 +00:00
|
|
|
/* make sure sff pio task is not running */
|
|
|
|
ata_sff_flush_pio_task(ap);
|
2006-04-02 09:51:53 +00:00
|
|
|
|
2006-08-24 07:19:22 +00:00
|
|
|
/* synchronize with host lock and sort out timeouts */
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
/*
|
2023-07-31 14:34:12 +00:00
|
|
|
* For EH, all qcs are finished in one of three ways -
|
2006-05-15 11:58:12 +00:00
|
|
|
* normal completion, error completion, and SCSI timeout.
|
2009-03-24 10:23:46 +00:00
|
|
|
* Both completions can race against SCSI timeout. When normal
|
2006-05-15 11:58:12 +00:00
|
|
|
* completion wins, the qc never reaches EH. When error
|
2022-12-29 16:59:57 +00:00
|
|
|
* completion wins, the qc has ATA_QCFLAG_EH set.
|
2006-05-15 11:58:12 +00:00
|
|
|
*
|
|
|
|
* When SCSI timeout wins, things are a bit more complex.
|
|
|
|
* Normal or error completion can occur after the timeout but
|
|
|
|
* before this point. In such cases, both types of
|
|
|
|
* completions are honored. A scmd is determined to have
|
|
|
|
* timed out iff its associated qc is active and not failed.
|
|
|
|
*/
|
2017-06-29 20:10:47 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2010-05-25 19:31:38 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
/*
|
|
|
|
* This must occur under the ap->lock as we don't want
|
|
|
|
* a polled recovery to race the real interrupt handler
|
|
|
|
*
|
|
|
|
* The lost_interrupt handler checks for any completed but
|
|
|
|
* non-notified command and completes much like an IRQ handler.
|
|
|
|
*
|
|
|
|
* We then fall into the error recovery code which will treat
|
|
|
|
* this as if normal completion won the race
|
|
|
|
*/
|
|
|
|
if (ap->ops->lost_interrupt)
|
|
|
|
ap->ops->lost_interrupt(ap);
|
2010-05-25 19:31:38 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
|
|
|
|
struct ata_queued_cmd *qc;
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
ata_qc_for_each_raw(ap, qc, i) {
|
|
|
|
if (qc->flags & ATA_QCFLAG_ACTIVE &&
|
|
|
|
qc->scsicmd == scmd)
|
|
|
|
break;
|
|
|
|
}
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
if (i < ATA_MAX_QUEUE) {
|
|
|
|
/* the scmd has an associated qc */
|
2022-12-29 16:59:57 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH)) {
|
2022-12-15 15:37:49 +00:00
|
|
|
/* which hasn't failed yet, timeout */
|
|
|
|
qc->err_mask |= AC_ERR_TIMEOUT;
|
2022-12-29 16:59:57 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_EH;
|
2022-12-15 15:37:49 +00:00
|
|
|
nr_timedout++;
|
2006-05-15 11:58:12 +00:00
|
|
|
}
|
2022-12-15 15:37:49 +00:00
|
|
|
} else {
|
|
|
|
/* Normal completion occurred after
|
|
|
|
* SCSI timeout but before this point.
|
|
|
|
* Successfully complete it.
|
|
|
|
*/
|
|
|
|
scmd->retries = scmd->allowed;
|
|
|
|
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
|
2006-05-15 11:58:12 +00:00
|
|
|
}
|
2022-12-15 15:37:49 +00:00
|
|
|
}
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
/*
|
|
|
|
* If we have timed out qcs. They belong to EH from
|
|
|
|
* this point but the state of the controller is
|
|
|
|
* unknown. Freeze the port to make sure the IRQ
|
|
|
|
* handler doesn't diddle with those qcs. This must
|
2022-12-29 16:59:57 +00:00
|
|
|
* be done atomically w.r.t. setting ATA_QCFLAG_EH.
|
2022-12-15 15:37:49 +00:00
|
|
|
*/
|
|
|
|
if (nr_timedout)
|
|
|
|
__ata_port_freeze(ap);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2022-12-15 15:37:49 +00:00
|
|
|
/* initialize eh_tries */
|
|
|
|
ap->eh_tries = ATA_EH_MAX_TRIES;
|
2007-08-18 04:28:49 +00:00
|
|
|
|
2017-06-29 20:10:47 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2011-01-23 15:42:50 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_scsi_port_error_handler - recover the port after the commands
|
|
|
|
* @host: SCSI host containing the port
|
|
|
|
* @ap: the ATA port
|
|
|
|
*
|
|
|
|
* Handle the recovery of the port @ap after all the commands
|
|
|
|
* have been recovered.
|
|
|
|
*/
|
|
|
|
void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
2023-07-31 14:34:12 +00:00
|
|
|
struct ata_link *link;
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* acquire EH ownership */
|
|
|
|
ata_eh_acquire(ap);
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
repeat:
|
2023-07-31 14:34:12 +00:00
|
|
|
/* kill fast drain timer */
|
|
|
|
del_timer_sync(&ap->fastdrain_timer);
|
2007-07-16 05:29:41 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* process port resume request */
|
|
|
|
ata_eh_handle_port_resume(ap);
|
2006-07-03 07:07:27 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* fetch & clear EH info */
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-15 11:58:21 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
ata_for_each_link(link, ap, HOST_FIRST) {
|
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
|
|
|
struct ata_device *dev;
|
2007-11-27 10:28:58 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
memset(&link->eh_context, 0, sizeof(link->eh_context));
|
|
|
|
link->eh_context.i = link->eh_info;
|
|
|
|
memset(&link->eh_info, 0, sizeof(link->eh_info));
|
2007-11-27 10:28:58 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
ata_for_each_dev(dev, link, ENABLED) {
|
|
|
|
int devno = dev->devno;
|
2007-11-27 10:28:58 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
ehc->saved_xfer_mode[devno] = dev->xfer_mode;
|
|
|
|
if (ata_ncq_enabled(dev))
|
|
|
|
ehc->saved_ncq_enabled |= 1 << devno;
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
|
|
|
|
/* If we are resuming, wake up the device */
|
|
|
|
if (ap->pflags & ATA_PFLAG_RESUMING)
|
|
|
|
ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE;
|
2007-08-06 09:36:23 +00:00
|
|
|
}
|
2023-07-31 14:34:12 +00:00
|
|
|
}
|
2006-05-15 11:58:21 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
|
|
|
|
ap->pflags &= ~ATA_PFLAG_EH_PENDING;
|
|
|
|
ap->excl_link = NULL; /* don't maintain exclusion over EH */
|
2006-05-15 11:58:21 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* invoke EH, skip if unloading or suspended */
|
|
|
|
if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED)))
|
|
|
|
ap->ops->error_handler(ap);
|
|
|
|
else {
|
|
|
|
/* if unloading, commence suicide */
|
|
|
|
if ((ap->pflags & ATA_PFLAG_UNLOADING) &&
|
|
|
|
!(ap->pflags & ATA_PFLAG_UNLOADED))
|
|
|
|
ata_eh_unload(ap);
|
|
|
|
ata_eh_finish(ap);
|
|
|
|
}
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* process port suspend request */
|
|
|
|
ata_eh_handle_port_suspend(ap);
|
2006-07-03 07:07:27 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/*
|
|
|
|
* Exception might have happened after ->error_handler recovered the
|
|
|
|
* port but before this point. Repeat EH in such case.
|
|
|
|
*/
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
if (ap->pflags & ATA_PFLAG_EH_PENDING) {
|
|
|
|
if (--ap->eh_tries) {
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
goto repeat;
|
2006-05-15 11:58:12 +00:00
|
|
|
}
|
2023-07-31 14:34:12 +00:00
|
|
|
ata_port_err(ap,
|
|
|
|
"EH pending after %d tries, giving up\n",
|
|
|
|
ATA_EH_MAX_TRIES);
|
|
|
|
ap->pflags &= ~ATA_PFLAG_EH_PENDING;
|
|
|
|
}
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/* this run is complete, make sure EH info is clear */
|
|
|
|
ata_for_each_link(link, ap, HOST_FIRST)
|
|
|
|
memset(&link->eh_info, 0, sizeof(link->eh_info));
|
2006-05-15 11:58:21 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
/*
|
|
|
|
* end eh (clear host_eh_scheduled) while holding ap->lock such that if
|
|
|
|
* exception occurs after this point but before EH completion, SCSI
|
|
|
|
* midlayer will re-initiate EH.
|
|
|
|
*/
|
|
|
|
ap->ops->end_eh(ap);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2023-07-31 14:34:12 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
ata_eh_release(ap);
|
2006-04-02 09:51:53 +00:00
|
|
|
|
|
|
|
scsi_eh_flush_done_q(&ap->eh_done_q);
|
|
|
|
|
2006-05-15 11:58:12 +00:00
|
|
|
/* clean up */
|
2006-07-02 18:02:15 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
ap->pflags &= ~ATA_PFLAG_RESUMING;
|
|
|
|
|
2006-07-03 07:07:26 +00:00
|
|
|
if (ap->pflags & ATA_PFLAG_LOADING)
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags &= ~ATA_PFLAG_LOADING;
|
2018-02-28 01:11:10 +00:00
|
|
|
else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) &&
|
|
|
|
!(ap->flags & ATA_FLAG_SAS_HOST))
|
2010-07-02 08:03:52 +00:00
|
|
|
schedule_delayed_work(&ap->hotplug_task, 0);
|
2006-07-03 07:07:26 +00:00
|
|
|
|
|
|
|
if (ap->pflags & ATA_PFLAG_RECOVERED)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_port_info(ap, "EH complete\n");
|
2006-05-31 09:28:05 +00:00
|
|
|
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags &= ~(ATA_PFLAG_SCSI_HOTPLUG | ATA_PFLAG_RECOVERED);
|
2006-05-15 11:58:12 +00:00
|
|
|
|
2006-05-31 09:27:27 +00:00
|
|
|
/* tell wait_eh that we're done */
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags &= ~ATA_PFLAG_EH_IN_PROGRESS;
|
2006-05-31 09:27:27 +00:00
|
|
|
wake_up_all(&ap->eh_wait_q);
|
|
|
|
|
2006-07-02 18:02:15 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-04-02 09:51:53 +00:00
|
|
|
}
|
2011-01-23 15:42:50 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_scsi_port_error_handler);
|
2006-04-02 09:51:53 +00:00
|
|
|
|
2006-05-31 09:27:27 +00:00
|
|
|
/**
|
|
|
|
* ata_port_wait_eh - Wait for the currently pending EH to complete
|
|
|
|
* @ap: Port to wait EH for
|
|
|
|
*
|
|
|
|
* Wait until the currently pending EH is complete.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
|
|
|
void ata_port_wait_eh(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
DEFINE_WAIT(wait);
|
|
|
|
|
|
|
|
retry:
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-31 09:27:27 +00:00
|
|
|
|
2006-06-28 16:29:30 +00:00
|
|
|
while (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) {
|
2006-05-31 09:27:27 +00:00
|
|
|
prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE);
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-31 09:27:27 +00:00
|
|
|
schedule();
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-31 09:27:27 +00:00
|
|
|
}
|
2006-06-11 02:01:38 +00:00
|
|
|
finish_wait(&ap->eh_wait_q, &wait);
|
2006-05-31 09:27:27 +00:00
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-31 09:27:27 +00:00
|
|
|
|
|
|
|
/* make sure SCSI EH is complete */
|
2006-08-24 07:19:22 +00:00
|
|
|
if (scsi_host_in_recovery(ap->scsi_host)) {
|
2010-09-06 15:56:29 +00:00
|
|
|
ata_msleep(ap, 10);
|
2006-05-31 09:27:27 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
}
|
2011-12-03 00:07:01 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_wait_eh);
|
2006-05-31 09:27:27 +00:00
|
|
|
|
2022-06-16 20:51:48 +00:00
|
|
|
static unsigned int ata_eh_nr_in_flight(struct ata_port *ap)
|
2007-07-16 05:29:41 +00:00
|
|
|
{
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2007-07-16 05:29:41 +00:00
|
|
|
unsigned int tag;
|
2022-06-16 20:51:48 +00:00
|
|
|
unsigned int nr = 0;
|
2007-07-16 05:29:41 +00:00
|
|
|
|
|
|
|
/* count only non-internal commands */
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each(ap, qc, tag) {
|
|
|
|
if (qc)
|
2007-07-16 05:29:41 +00:00
|
|
|
nr++;
|
2018-05-11 18:51:07 +00:00
|
|
|
}
|
2007-07-16 05:29:41 +00:00
|
|
|
|
|
|
|
return nr;
|
|
|
|
}
|
|
|
|
|
2017-10-16 21:56:42 +00:00
|
|
|
void ata_eh_fastdrain_timerfn(struct timer_list *t)
|
2007-07-16 05:29:41 +00:00
|
|
|
{
|
2017-10-16 21:56:42 +00:00
|
|
|
struct ata_port *ap = from_timer(ap, t, fastdrain_timer);
|
2007-07-16 05:29:41 +00:00
|
|
|
unsigned long flags;
|
2022-06-16 20:51:48 +00:00
|
|
|
unsigned int cnt;
|
2007-07-16 05:29:41 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
|
|
|
|
cnt = ata_eh_nr_in_flight(ap);
|
|
|
|
|
|
|
|
/* are we done? */
|
|
|
|
if (!cnt)
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
if (cnt == ap->fastdrain_cnt) {
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2007-07-16 05:29:41 +00:00
|
|
|
unsigned int tag;
|
|
|
|
|
|
|
|
/* No progress during the last interval, tag all
|
|
|
|
* in-flight qcs as timed out and freeze the port.
|
|
|
|
*/
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each(ap, qc, tag) {
|
2007-07-16 05:29:41 +00:00
|
|
|
if (qc)
|
|
|
|
qc->err_mask |= AC_ERR_TIMEOUT;
|
|
|
|
}
|
|
|
|
|
|
|
|
ata_port_freeze(ap);
|
|
|
|
} else {
|
|
|
|
/* some qcs have finished, give it another chance */
|
|
|
|
ap->fastdrain_cnt = cnt;
|
|
|
|
ap->fastdrain_timer.expires =
|
2008-05-19 17:17:51 +00:00
|
|
|
ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL);
|
2007-07-16 05:29:41 +00:00
|
|
|
add_timer(&ap->fastdrain_timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_set_pending - set ATA_PFLAG_EH_PENDING and activate fast drain
|
|
|
|
* @ap: target ATA port
|
|
|
|
* @fastdrain: activate fast drain
|
|
|
|
*
|
|
|
|
* Set ATA_PFLAG_EH_PENDING and activate fast drain if @fastdrain
|
|
|
|
* is non-zero and EH wasn't pending before. Fast drain ensures
|
|
|
|
* that EH kicks in in timely manner.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
|
|
|
|
{
|
2022-06-16 20:51:48 +00:00
|
|
|
unsigned int cnt;
|
2007-07-16 05:29:41 +00:00
|
|
|
|
|
|
|
/* already scheduled? */
|
|
|
|
if (ap->pflags & ATA_PFLAG_EH_PENDING)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ap->pflags |= ATA_PFLAG_EH_PENDING;
|
|
|
|
|
|
|
|
if (!fastdrain)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* do we have in-flight qcs? */
|
|
|
|
cnt = ata_eh_nr_in_flight(ap);
|
|
|
|
if (!cnt)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* activate fast drain */
|
|
|
|
ap->fastdrain_cnt = cnt;
|
2008-05-19 17:17:51 +00:00
|
|
|
ap->fastdrain_timer.expires =
|
|
|
|
ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL);
|
2007-07-16 05:29:41 +00:00
|
|
|
add_timer(&ap->fastdrain_timer);
|
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:05 +00:00
|
|
|
/**
|
|
|
|
* ata_qc_schedule_eh - schedule qc for error handling
|
|
|
|
* @qc: command to schedule error handling for
|
|
|
|
*
|
|
|
|
* Schedule error handling for @qc. EH will kick in as soon as
|
|
|
|
* other commands are drained.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
2006-08-24 07:19:22 +00:00
|
|
|
* spin_lock_irqsave(host lock)
|
2006-05-15 11:58:05 +00:00
|
|
|
*/
|
|
|
|
void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
|
|
|
|
{
|
|
|
|
struct ata_port *ap = qc->ap;
|
|
|
|
|
2022-12-29 16:59:57 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_EH;
|
2007-07-16 05:29:41 +00:00
|
|
|
ata_eh_set_pending(ap, 1);
|
2006-05-15 11:58:05 +00:00
|
|
|
|
|
|
|
/* The following will fail if timeout has already expired.
|
|
|
|
* ata_scsi_error() takes care of such scmds on EH entry.
|
2022-12-29 16:59:57 +00:00
|
|
|
* Note that ATA_QCFLAG_EH is unconditionally set after
|
2006-05-15 11:58:05 +00:00
|
|
|
* this function completes.
|
|
|
|
*/
|
2021-08-09 23:03:10 +00:00
|
|
|
blk_abort_request(scsi_cmd_to_rq(qc->scsicmd));
|
2006-05-15 11:58:05 +00:00
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:07 +00:00
|
|
|
/**
|
2012-06-22 06:25:27 +00:00
|
|
|
* ata_std_sched_eh - non-libsas ata_ports issue eh with this common routine
|
|
|
|
* @ap: ATA port to schedule EH for
|
2006-05-15 11:58:07 +00:00
|
|
|
*
|
2012-06-22 06:25:27 +00:00
|
|
|
* LOCKING: inherited from ata_port_schedule_eh
|
2006-08-24 07:19:22 +00:00
|
|
|
* spin_lock_irqsave(host lock)
|
2006-05-15 11:58:07 +00:00
|
|
|
*/
|
2012-06-22 06:25:27 +00:00
|
|
|
void ata_std_sched_eh(struct ata_port *ap)
|
2006-05-15 11:58:07 +00:00
|
|
|
{
|
2007-05-01 09:50:15 +00:00
|
|
|
if (ap->pflags & ATA_PFLAG_INITIALIZING)
|
|
|
|
return;
|
|
|
|
|
2007-07-16 05:29:41 +00:00
|
|
|
ata_eh_set_pending(ap, 1);
|
2006-08-24 07:19:22 +00:00
|
|
|
scsi_schedule_eh(ap->scsi_host);
|
2006-05-15 11:58:07 +00:00
|
|
|
|
2021-12-21 07:20:34 +00:00
|
|
|
trace_ata_std_sched_eh(ap);
|
2006-05-15 11:58:07 +00:00
|
|
|
}
|
2012-06-22 06:25:27 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_std_sched_eh);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_std_end_eh - non-libsas ata_ports complete eh with this common routine
|
|
|
|
* @ap: ATA port to end EH for
|
|
|
|
*
|
|
|
|
* In the libata object model there is a 1:1 mapping of ata_port to
|
|
|
|
* shost, so host fields can be directly manipulated under ap->lock, in
|
|
|
|
* the libsas case we need to hold a lock at the ha->level to coordinate
|
|
|
|
* these events.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
void ata_std_end_eh(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
struct Scsi_Host *host = ap->scsi_host;
|
|
|
|
|
|
|
|
host->host_eh_scheduled = 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ata_std_end_eh);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_port_schedule_eh - schedule error handling without a qc
|
|
|
|
* @ap: ATA port to schedule EH for
|
|
|
|
*
|
|
|
|
* Schedule error handling for @ap. EH will kick in as soon as
|
|
|
|
* all commands are drained.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*/
|
|
|
|
void ata_port_schedule_eh(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
/* see: ata_std_sched_eh, unless you know better */
|
|
|
|
ap->ops->sched_eh(ap);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
|
2006-05-15 11:58:07 +00:00
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
|
2006-05-15 11:58:07 +00:00
|
|
|
{
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2006-05-15 11:58:07 +00:00
|
|
|
int tag, nr_aborted = 0;
|
|
|
|
|
2007-07-16 05:29:41 +00:00
|
|
|
/* we're gonna abort all commands, no need for fast drain */
|
|
|
|
ata_eh_set_pending(ap, 0);
|
|
|
|
|
2018-05-11 18:51:09 +00:00
|
|
|
/* include internal tag in iteration */
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each_with_internal(ap, qc, tag) {
|
2007-08-06 09:36:23 +00:00
|
|
|
if (qc && (!link || qc->dev->link == link)) {
|
2022-12-29 16:59:57 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_EH;
|
2006-05-15 11:58:07 +00:00
|
|
|
ata_qc_complete(qc);
|
|
|
|
nr_aborted++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nr_aborted)
|
|
|
|
ata_port_schedule_eh(ap);
|
|
|
|
|
|
|
|
return nr_aborted;
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
/**
|
|
|
|
* ata_link_abort - abort all qc's on the link
|
|
|
|
* @link: ATA link to abort qc's for
|
|
|
|
*
|
|
|
|
* Abort all active qc's active on @link and schedule EH.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host lock)
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Number of aborted qc's.
|
|
|
|
*/
|
|
|
|
int ata_link_abort(struct ata_link *link)
|
|
|
|
{
|
|
|
|
return ata_do_link_abort(link->ap, link);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_link_abort);
|
2007-08-06 09:36:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_port_abort - abort all qc's on the port
|
|
|
|
* @ap: ATA port to abort qc's for
|
|
|
|
*
|
|
|
|
* Abort all active qc's of @ap and schedule EH.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* spin_lock_irqsave(host_set lock)
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Number of aborted qc's.
|
|
|
|
*/
|
|
|
|
int ata_port_abort(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
return ata_do_link_abort(ap, NULL);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_abort);
|
2007-08-06 09:36:23 +00:00
|
|
|
|
2006-05-15 11:58:09 +00:00
|
|
|
/**
|
|
|
|
* __ata_port_freeze - freeze port
|
|
|
|
* @ap: ATA port to freeze
|
|
|
|
*
|
|
|
|
* This function is called when HSM violation or some other
|
|
|
|
* condition disrupts normal operation of the port. Frozen port
|
|
|
|
* is not allowed to perform any operation until the port is
|
|
|
|
* thawed, which usually follows a successful reset.
|
|
|
|
*
|
|
|
|
* ap->ops->freeze() callback can be used for freezing the port
|
|
|
|
* hardware-wise (e.g. mask interrupt and stop DMA engine). If a
|
|
|
|
* port cannot be frozen hardware-wise, the interrupt handler
|
|
|
|
* must ack and clear interrupts unconditionally while the port
|
|
|
|
* is frozen.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
2006-08-24 07:19:22 +00:00
|
|
|
* spin_lock_irqsave(host lock)
|
2006-05-15 11:58:09 +00:00
|
|
|
*/
|
|
|
|
static void __ata_port_freeze(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
if (ap->ops->freeze)
|
|
|
|
ap->ops->freeze(ap);
|
|
|
|
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags |= ATA_PFLAG_FROZEN;
|
2006-05-15 11:58:09 +00:00
|
|
|
|
2021-12-21 07:20:34 +00:00
|
|
|
trace_ata_port_freeze(ap);
|
2006-05-15 11:58:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_port_freeze - abort & freeze port
|
|
|
|
* @ap: ATA port to freeze
|
|
|
|
*
|
2009-04-07 23:13:15 +00:00
|
|
|
* Abort and freeze @ap. The freeze operation must be called
|
|
|
|
* first, because some hardware requires special operations
|
|
|
|
* before the taskfile registers are accessible.
|
2006-05-15 11:58:09 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
2006-08-24 07:19:22 +00:00
|
|
|
* spin_lock_irqsave(host lock)
|
2006-05-15 11:58:09 +00:00
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Number of aborted commands.
|
|
|
|
*/
|
|
|
|
int ata_port_freeze(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
__ata_port_freeze(ap);
|
|
|
|
|
2022-09-20 06:29:29 +00:00
|
|
|
return ata_port_abort(ap);
|
2006-05-15 11:58:09 +00:00
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_port_freeze);
|
2006-05-15 11:58:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_freeze_port - EH helper to freeze port
|
|
|
|
* @ap: ATA port to freeze
|
|
|
|
*
|
|
|
|
* Freeze @ap.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
|
|
|
void ata_eh_freeze_port(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-15 11:58:09 +00:00
|
|
|
__ata_port_freeze(ap);
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-15 11:58:09 +00:00
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
|
2006-05-15 11:58:09 +00:00
|
|
|
|
|
|
|
/**
|
2020-10-23 16:32:55 +00:00
|
|
|
* ata_eh_thaw_port - EH helper to thaw port
|
2006-05-15 11:58:09 +00:00
|
|
|
* @ap: ATA port to thaw
|
|
|
|
*
|
|
|
|
* Thaw frozen port @ap.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
|
|
|
void ata_eh_thaw_port(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-15 11:58:09 +00:00
|
|
|
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags &= ~ATA_PFLAG_FROZEN;
|
2006-05-15 11:58:09 +00:00
|
|
|
|
|
|
|
if (ap->ops->thaw)
|
|
|
|
ap->ops->thaw(ap);
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-15 11:58:09 +00:00
|
|
|
|
2021-12-21 07:20:34 +00:00
|
|
|
trace_ata_port_thaw(ap);
|
2006-05-15 11:58:09 +00:00
|
|
|
}
|
|
|
|
|
2006-04-02 09:51:53 +00:00
|
|
|
static void ata_eh_scsidone(struct scsi_cmnd *scmd)
|
|
|
|
{
|
|
|
|
/* nada */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
|
|
|
|
{
|
|
|
|
struct ata_port *ap = qc->ap;
|
|
|
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
|
|
|
unsigned long flags;
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-04-02 09:51:53 +00:00
|
|
|
qc->scsidone = ata_eh_scsidone;
|
|
|
|
__ata_qc_complete(qc);
|
|
|
|
WARN_ON(ata_tag_valid(qc->tag));
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-04-02 09:51:53 +00:00
|
|
|
|
|
|
|
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_qc_complete - Complete an active ATA command from EH
|
|
|
|
* @qc: Command to complete
|
|
|
|
*
|
|
|
|
* Indicate to the mid and upper layers that an ATA command has
|
|
|
|
* completed. To be used from EH.
|
|
|
|
*/
|
|
|
|
void ata_eh_qc_complete(struct ata_queued_cmd *qc)
|
|
|
|
{
|
|
|
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
|
|
|
scmd->retries = scmd->allowed;
|
|
|
|
__ata_eh_qc_complete(qc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
|
|
|
|
* @qc: Command to retry
|
|
|
|
*
|
|
|
|
* Indicate to the mid and upper layers that an ATA command
|
|
|
|
* should be retried. To be used from EH.
|
|
|
|
*
|
|
|
|
* SCSI midlayer limits the number of retries to scmd->allowed.
|
2009-08-07 23:17:49 +00:00
|
|
|
* scmd->allowed is incremented for commands which get retried
|
2006-04-02 09:51:53 +00:00
|
|
|
* due to unrelated failures (qc->err_mask is zero).
|
|
|
|
*/
|
|
|
|
void ata_eh_qc_retry(struct ata_queued_cmd *qc)
|
|
|
|
{
|
|
|
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
2009-08-07 23:17:49 +00:00
|
|
|
if (!qc->err_mask)
|
|
|
|
scmd->allowed++;
|
2006-04-02 09:51:53 +00:00
|
|
|
__ata_eh_qc_complete(qc);
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2009-01-29 11:31:30 +00:00
|
|
|
/**
|
|
|
|
* ata_dev_disable - disable ATA device
|
|
|
|
* @dev: ATA device to disable
|
|
|
|
*
|
|
|
|
* Disable @dev.
|
|
|
|
*
|
|
|
|
* Locking:
|
|
|
|
* EH context.
|
|
|
|
*/
|
|
|
|
void ata_dev_disable(struct ata_device *dev)
|
|
|
|
{
|
|
|
|
if (!ata_dev_enabled(dev))
|
|
|
|
return;
|
|
|
|
|
2021-12-21 07:21:07 +00:00
|
|
|
ata_dev_warn(dev, "disable device\n");
|
2009-01-29 11:31:30 +00:00
|
|
|
ata_acpi_on_disable(dev);
|
|
|
|
ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
|
|
|
|
dev->class++;
|
2009-01-29 11:31:32 +00:00
|
|
|
|
|
|
|
/* From now till the next successful probe, ering is used to
|
|
|
|
* track probe failures. Clear accumulated device error info.
|
|
|
|
*/
|
|
|
|
ata_ering_clear(&dev->ering);
|
2009-01-29 11:31:30 +00:00
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_dev_disable);
|
2009-01-29 11:31:30 +00:00
|
|
|
|
2006-05-31 09:28:01 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_detach_dev - detach ATA device
|
|
|
|
* @dev: ATA device to detach
|
|
|
|
*
|
|
|
|
* Detach @dev.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_detach_dev(struct ata_device *dev)
|
2006-05-31 09:28:01 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_link *link = dev->link;
|
|
|
|
struct ata_port *ap = link->ap;
|
2008-10-26 06:43:03 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-31 09:28:01 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
/*
|
|
|
|
* If the device is still enabled, transition it to standby power mode
|
|
|
|
* (i.e. spin down HDDs).
|
|
|
|
*/
|
|
|
|
if (ata_dev_enabled(dev))
|
|
|
|
ata_dev_power_set_standby(dev);
|
|
|
|
|
2006-05-31 09:28:01 +00:00
|
|
|
ata_dev_disable(dev);
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-05-31 09:28:01 +00:00
|
|
|
|
|
|
|
dev->flags &= ~ATA_DFLAG_DETACH;
|
|
|
|
|
|
|
|
if (ata_scsi_offline_dev(dev)) {
|
|
|
|
dev->flags |= ATA_DFLAG_DETACHED;
|
2006-06-28 16:29:30 +00:00
|
|
|
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
|
2006-05-31 09:28:01 +00:00
|
|
|
}
|
|
|
|
|
2008-10-26 06:43:03 +00:00
|
|
|
/* clear per-dev EH info */
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_clear_action(link, dev, &link->eh_info, ATA_EH_PERDEV_MASK);
|
|
|
|
ata_eh_clear_action(link, dev, &link->eh_context.i, ATA_EH_PERDEV_MASK);
|
2008-10-26 06:43:03 +00:00
|
|
|
ehc->saved_xfer_mode[dev->devno] = 0;
|
|
|
|
ehc->saved_ncq_enabled &= ~(1 << dev->devno);
|
2006-06-24 11:30:19 +00:00
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-31 09:28:01 +00:00
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_about_to_do - about to perform eh_action
|
2007-08-06 09:36:23 +00:00
|
|
|
* @link: target ATA link
|
2006-06-19 09:27:23 +00:00
|
|
|
* @dev: target ATA dev for per-dev action (can be NULL)
|
2006-05-15 11:58:22 +00:00
|
|
|
* @action: action about to be performed
|
|
|
|
*
|
|
|
|
* Called just before performing EH actions to clear related bits
|
2007-08-06 09:36:23 +00:00
|
|
|
* in @link->eh_info such that eh actions are not unnecessarily
|
|
|
|
* repeated.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
|
|
|
|
unsigned int action)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_eh_info *ehi = &link->eh_info;
|
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-15 11:58:22 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
2021-12-21 07:20:34 +00:00
|
|
|
trace_ata_eh_about_to_do(link, dev ? dev->devno : 0, action);
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2006-07-03 07:07:26 +00:00
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_clear_action(link, dev, ehi, action);
|
2006-07-03 07:07:26 +00:00
|
|
|
|
2008-10-21 11:37:21 +00:00
|
|
|
/* About to take EH action, set RECOVERED. Ignore actions on
|
|
|
|
* slave links as master will do them again.
|
|
|
|
*/
|
|
|
|
if (!(ehc->i.flags & ATA_EHI_QUIET) && link != ap->slave_link)
|
2006-07-03 07:07:26 +00:00
|
|
|
ap->pflags |= ATA_PFLAG_RECOVERED;
|
|
|
|
|
2006-06-23 03:46:10 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2006-06-19 09:27:23 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_done - EH action complete
|
2017-07-30 22:16:04 +00:00
|
|
|
* @link: ATA link for which EH actions are complete
|
2006-06-19 09:27:23 +00:00
|
|
|
* @dev: target ATA dev for per-dev action (can be NULL)
|
|
|
|
* @action: action just completed
|
|
|
|
*
|
|
|
|
* Called right after performing EH actions to clear related bits
|
2007-08-06 09:36:23 +00:00
|
|
|
* in @link->eh_context.
|
2006-06-19 09:27:23 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_done(struct ata_link *link, struct ata_device *dev,
|
|
|
|
unsigned int action)
|
2006-06-19 09:27:23 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2007-08-06 09:36:22 +00:00
|
|
|
|
2021-12-21 07:20:34 +00:00
|
|
|
trace_ata_eh_done(link, dev ? dev->devno : 0, action);
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_clear_action(link, dev, &ehc->i, action);
|
2006-06-19 09:27:23 +00:00
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/**
|
|
|
|
* ata_err_string - convert err_mask to descriptive string
|
|
|
|
* @err_mask: error mask to convert to string
|
|
|
|
*
|
|
|
|
* Convert @err_mask to descriptive string. Errors are
|
|
|
|
* prioritized according to severity and only the most severe
|
|
|
|
* error is reported.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Descriptive string for @err_mask
|
|
|
|
*/
|
2007-10-19 10:42:56 +00:00
|
|
|
static const char *ata_err_string(unsigned int err_mask)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
|
|
|
if (err_mask & AC_ERR_HOST_BUS)
|
|
|
|
return "host bus error";
|
|
|
|
if (err_mask & AC_ERR_ATA_BUS)
|
|
|
|
return "ATA bus error";
|
|
|
|
if (err_mask & AC_ERR_TIMEOUT)
|
|
|
|
return "timeout";
|
|
|
|
if (err_mask & AC_ERR_HSM)
|
|
|
|
return "HSM violation";
|
|
|
|
if (err_mask & AC_ERR_SYSTEM)
|
|
|
|
return "internal error";
|
|
|
|
if (err_mask & AC_ERR_MEDIA)
|
|
|
|
return "media error";
|
|
|
|
if (err_mask & AC_ERR_INVALID)
|
|
|
|
return "invalid argument";
|
|
|
|
if (err_mask & AC_ERR_DEV)
|
|
|
|
return "device error";
|
2018-05-09 00:28:09 +00:00
|
|
|
if (err_mask & AC_ERR_NCQ)
|
|
|
|
return "NCQ error";
|
|
|
|
if (err_mask & AC_ERR_NODEV_HINT)
|
|
|
|
return "Polling detection error";
|
2006-05-15 11:58:22 +00:00
|
|
|
return "unknown error";
|
|
|
|
}
|
|
|
|
|
2008-08-30 12:20:01 +00:00
|
|
|
/**
|
|
|
|
* atapi_eh_tur - perform ATAPI TEST_UNIT_READY
|
|
|
|
* @dev: target ATAPI device
|
|
|
|
* @r_sense_key: out parameter for sense_key
|
|
|
|
*
|
|
|
|
* Perform ATAPI TEST_UNIT_READY.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, AC_ERR_* mask on failure.
|
|
|
|
*/
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
|
2008-08-30 12:20:01 +00:00
|
|
|
{
|
|
|
|
u8 cdb[ATAPI_CDB_LEN] = { TEST_UNIT_READY, 0, 0, 0, 0, 0 };
|
|
|
|
struct ata_taskfile tf;
|
|
|
|
unsigned int err_mask;
|
|
|
|
|
|
|
|
ata_tf_init(dev, &tf);
|
|
|
|
|
|
|
|
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
|
|
|
tf.command = ATA_CMD_PACKET;
|
|
|
|
tf.protocol = ATAPI_PROT_NODATA;
|
|
|
|
|
|
|
|
err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
|
|
|
|
if (err_mask == AC_ERR_DEV)
|
2022-02-15 18:49:26 +00:00
|
|
|
*r_sense_key = tf.error >> 4;
|
2008-08-30 12:20:01 +00:00
|
|
|
return err_mask;
|
|
|
|
}
|
|
|
|
|
2016-04-04 09:43:55 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT
|
2017-07-30 22:16:04 +00:00
|
|
|
* @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to
|
2016-04-04 09:43:55 +00:00
|
|
|
*
|
|
|
|
* Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK
|
|
|
|
* SENSE. This function is an EH helper.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* true if sense data could be fetched, false otherwise.
|
2016-04-04 09:43:55 +00:00
|
|
|
*/
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
static bool ata_eh_request_sense(struct ata_queued_cmd *qc)
|
2016-04-04 09:43:55 +00:00
|
|
|
{
|
2022-09-16 12:28:36 +00:00
|
|
|
struct scsi_cmnd *cmd = qc->scsicmd;
|
2016-04-04 09:43:55 +00:00
|
|
|
struct ata_device *dev = qc->dev;
|
|
|
|
struct ata_taskfile tf;
|
|
|
|
unsigned int err_mask;
|
|
|
|
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(qc->ap)) {
|
2016-04-04 09:43:55 +00:00
|
|
|
ata_dev_warn(dev, "sense data available but port frozen\n");
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
return false;
|
2016-04-04 09:43:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!ata_id_sense_reporting_enabled(dev->id)) {
|
|
|
|
ata_dev_warn(qc->dev, "sense data reporting disabled\n");
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
return false;
|
2016-04-04 09:43:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ata_tf_init(dev, &tf);
|
|
|
|
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
|
|
|
tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
|
|
|
|
tf.command = ATA_CMD_REQ_SENSE_DATA;
|
|
|
|
tf.protocol = ATA_PROT_NODATA;
|
|
|
|
|
|
|
|
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
|
|
|
/* Ignore err_mask; ATA_ERR might be set */
|
2022-02-15 18:49:26 +00:00
|
|
|
if (tf.status & ATA_SENSE) {
|
2022-09-26 20:53:07 +00:00
|
|
|
if (ata_scsi_sense_is_valid(tf.lbah, tf.lbam, tf.lbal)) {
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
/* Set sense without also setting scsicmd->result */
|
|
|
|
scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE,
|
|
|
|
cmd->sense_buffer, tf.lbah,
|
|
|
|
tf.lbam, tf.lbal);
|
2022-09-26 20:53:07 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
return true;
|
2022-09-26 20:53:07 +00:00
|
|
|
}
|
2016-04-04 09:43:55 +00:00
|
|
|
} else {
|
|
|
|
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
|
2022-02-15 18:49:26 +00:00
|
|
|
tf.status, err_mask);
|
2016-04-04 09:43:55 +00:00
|
|
|
}
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
|
|
|
|
return false;
|
2016-04-04 09:43:55 +00:00
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/**
|
|
|
|
* atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
|
|
|
|
* @dev: device to perform REQUEST_SENSE to
|
|
|
|
* @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long)
|
2008-06-10 09:28:05 +00:00
|
|
|
* @dfl_sense_key: default sense key to use
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* Perform ATAPI REQUEST_SENSE after the device reported CHECK
|
|
|
|
* SENSE. This function is EH helper.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, AC_ERR_* mask on failure
|
|
|
|
*/
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
unsigned int atapi_eh_request_sense(struct ata_device *dev,
|
2008-06-10 09:28:05 +00:00
|
|
|
u8 *sense_buf, u8 dfl_sense_key)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2008-06-10 09:28:05 +00:00
|
|
|
u8 cdb[ATAPI_CDB_LEN] =
|
|
|
|
{ REQUEST_SENSE, 0, 0, 0, SCSI_SENSE_BUFFERSIZE, 0 };
|
2007-08-06 09:36:22 +00:00
|
|
|
struct ata_port *ap = dev->link->ap;
|
2006-05-15 11:58:22 +00:00
|
|
|
struct ata_taskfile tf;
|
|
|
|
|
|
|
|
memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
|
|
|
|
|
2007-04-02 03:30:46 +00:00
|
|
|
/* initialize sense_buf with the error register,
|
|
|
|
* for the case where they are -not- overwritten
|
|
|
|
*/
|
2006-05-15 11:58:22 +00:00
|
|
|
sense_buf[0] = 0x70;
|
2008-06-10 09:28:05 +00:00
|
|
|
sense_buf[2] = dfl_sense_key;
|
2007-04-02 03:30:46 +00:00
|
|
|
|
2007-05-22 00:14:23 +00:00
|
|
|
/* some devices time out if garbage left in tf */
|
2007-04-02 03:30:46 +00:00
|
|
|
ata_tf_init(dev, &tf);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
|
|
|
tf.command = ATA_CMD_PACKET;
|
|
|
|
|
|
|
|
/* is it pointless to prefer PIO for "safety reasons"? */
|
|
|
|
if (ap->flags & ATA_FLAG_PIO_DMA) {
|
2007-12-18 21:34:43 +00:00
|
|
|
tf.protocol = ATAPI_PROT_DMA;
|
2006-05-15 11:58:22 +00:00
|
|
|
tf.feature |= ATAPI_PKT_DMA;
|
|
|
|
} else {
|
2007-12-18 21:34:43 +00:00
|
|
|
tf.protocol = ATAPI_PROT_PIO;
|
2007-12-12 03:12:46 +00:00
|
|
|
tf.lbam = SCSI_SENSE_BUFFERSIZE;
|
|
|
|
tf.lbah = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
|
2007-10-09 06:05:44 +00:00
|
|
|
sense_buf, SCSI_SENSE_BUFFERSIZE, 0);
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_analyze_serror - analyze SError for a failed port
|
2007-08-06 09:36:23 +00:00
|
|
|
* @link: ATA link to analyze SError for
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* Analyze SError if available and further determine cause of
|
|
|
|
* failure.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-08-06 09:36:23 +00:00
|
|
|
static void ata_eh_analyze_serror(struct ata_link *link)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-15 11:58:22 +00:00
|
|
|
u32 serror = ehc->i.serror;
|
|
|
|
unsigned int err_mask = 0, action = 0;
|
2007-09-23 04:14:13 +00:00
|
|
|
u32 hotplug_mask;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2008-05-18 16:15:09 +00:00
|
|
|
if (serror & (SERR_PERSISTENT | SERR_DATA)) {
|
2006-05-15 11:58:22 +00:00
|
|
|
err_mask |= AC_ERR_ATA_BUS;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
if (serror & SERR_PROTOCOL) {
|
|
|
|
err_mask |= AC_ERR_HSM;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
if (serror & SERR_INTERNAL) {
|
|
|
|
err_mask |= AC_ERR_SYSTEM;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
2007-09-23 04:14:13 +00:00
|
|
|
|
|
|
|
/* Determine whether a hotplug event has occurred. Both
|
|
|
|
* SError.N/X are considered hotplug events for enabled or
|
|
|
|
* host links. For disabled PMP links, only N bit is
|
|
|
|
* considered as X bit is left at 1 for link plugging.
|
|
|
|
*/
|
2011-02-24 18:30:37 +00:00
|
|
|
if (link->lpm_policy > ATA_LPM_MAX_POWER)
|
2010-09-01 15:50:06 +00:00
|
|
|
hotplug_mask = 0; /* hotplug doesn't work w/ LPM */
|
|
|
|
else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link))
|
2007-09-23 04:14:13 +00:00
|
|
|
hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG;
|
|
|
|
else
|
|
|
|
hotplug_mask = SERR_PHYRDY_CHG;
|
|
|
|
|
|
|
|
if (serror & hotplug_mask)
|
2006-05-31 09:28:03 +00:00
|
|
|
ata_ehi_hotplugged(&ehc->i);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
ehc->i.err_mask |= err_mask;
|
|
|
|
ehc->i.action |= action;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_analyze_tf - analyze taskfile of a failed qc
|
|
|
|
* @qc: qc to analyze
|
|
|
|
*
|
|
|
|
* Analyze taskfile of @qc and further determine cause of
|
|
|
|
* failure. This function also requests ATAPI sense data if
|
2011-03-31 01:57:33 +00:00
|
|
|
* available.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Determined recovery action
|
|
|
|
*/
|
2022-09-16 12:28:37 +00:00
|
|
|
static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2022-09-16 12:28:37 +00:00
|
|
|
const struct ata_taskfile *tf = &qc->result_tf;
|
2006-05-15 11:58:22 +00:00
|
|
|
unsigned int tmp, action = 0;
|
2022-02-15 18:49:26 +00:00
|
|
|
u8 stat = tf->status, err = tf->error;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
|
|
|
|
qc->err_mask |= AC_ERR_HSM;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
return ATA_EH_RESET;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 09:43:55 +00:00
|
|
|
if (stat & (ATA_ERR | ATA_DF)) {
|
2007-03-20 06:24:11 +00:00
|
|
|
qc->err_mask |= AC_ERR_DEV;
|
2016-04-04 09:43:55 +00:00
|
|
|
/*
|
|
|
|
* Sense data reporting does not work if the
|
|
|
|
* device fault bit is set.
|
|
|
|
*/
|
|
|
|
if (stat & ATA_DF)
|
|
|
|
stat &= ~ATA_SENSE;
|
|
|
|
} else {
|
2006-05-15 11:58:22 +00:00
|
|
|
return 0;
|
2016-04-04 09:43:55 +00:00
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
switch (qc->dev->class) {
|
ata: libata: fetch sense data for ATA devices supporting sense reporting
Currently, the sense data reporting feature set is enabled for all ATA
devices which supports the feature set (ata_id_has_sense_reporting()),
see ata_dev_config_sense_reporting().
However, even if sense data reporting is enabled, and the device
indicates that sense data is available, the sense data is only fetched
for ATA ZAC devices. For regular ATA devices, the available sense data
is never fetched, it is simply ignored. Instead, libata will use the
ERROR + STATUS fields and map them to a very generic and reduced set
of sense data, see ata_gen_ata_sense() and ata_to_sense_error().
When sense data reporting was first implemented, regular ATA devices
did fetch the sense data from the device. However, this was restricted
to only ATA ZAC devices in commit ca156e006add ("libata: don't request
sense data on !ZAC ATA devices").
With recent changes related to sense data and NCQ autosense, we want
to, once again, fetch the sense data for all ATA devices supporting
sense reporting.
ata_gen_ata_sense() should only be used for devices that don't support
the sense data reporting feature set.
hopefully the features will be more robust this time around.
It is not just ZAC, many new ATA features, e.g. Command Duration
Limits, relies on working NCQ autosense and sense data. Therefore,
it is not really an option to avoid fetching the sense data forever.
If we encounter a device that is misbehaving because the sense data is
actually fetched, then that device should be quirked such that it
never enables the sense data reporting feature set in the first place,
since such a device is obviously not compliant with the specification.
The order in which we will try to add sense data to a scsi_cmnd:
1) NCQ autosense (if supported) - ata_eh_analyze_ncq_error()
2) REQUEST SENSE DATA EXT (if supported) - ata_eh_request_sense()
3) error + status field translation - ata_gen_ata_sense(), called
by ata_scsi_qc_complete() if neither 1) or 2) is supported.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-09-26 20:53:08 +00:00
|
|
|
case ATA_DEV_ATA:
|
2014-11-05 12:08:21 +00:00
|
|
|
case ATA_DEV_ZAC:
|
2022-09-26 20:53:06 +00:00
|
|
|
/*
|
|
|
|
* Fetch the sense data explicitly if:
|
|
|
|
* -It was a non-NCQ command that failed, or
|
|
|
|
* -It was a NCQ command that failed, but the sense data
|
|
|
|
* was not included in the NCQ command error log
|
|
|
|
* (i.e. NCQ autosense is not supported by the device).
|
|
|
|
*/
|
scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result
to SAM_STAT_CHECK_CONDITION.
For Command Duration Limits policy 0xD:
The device shall complete the command without error (SAM_STAT_GOOD) with
the additional sense code set to DATA CURRENTLY UNAVAILABLE.
It is perfectly fine to have sense data for a command that returned
completion without error.
In order to support for CDL policy 0xD, we have to remove this assumption
that having sense data means that the command failed
(SAM_STAT_CHECK_CONDITION).
Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and
instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller
that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense()
can be reused in a follow-up patch that adds support for CDL policy 0xD.
The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags
& ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from
ata_eh_request_sense() itself.
Additionally, ata_eh_request_sense() is only called from
ata_eh_analyze_tf(), which is only called when iteratating the QCs using
ata_qc_for_each_raw(), which does not include the internal tag, so cmd can
never be NULL (all non-internal commands have qc->scsicmd set), so remove
the !cmd check as well.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:46 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_SENSE_VALID) &&
|
|
|
|
(stat & ATA_SENSE) && ata_eh_request_sense(qc))
|
|
|
|
set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION);
|
2006-05-15 11:58:22 +00:00
|
|
|
if (err & ATA_ICRC)
|
|
|
|
qc->err_mask |= AC_ERR_ATA_BUS;
|
2014-07-15 06:28:42 +00:00
|
|
|
if (err & (ATA_UNC | ATA_AMNF))
|
2006-05-15 11:58:22 +00:00
|
|
|
qc->err_mask |= AC_ERR_MEDIA;
|
|
|
|
if (err & ATA_IDNF)
|
|
|
|
qc->err_mask |= AC_ERR_INVALID;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ATA_DEV_ATAPI:
|
2022-10-07 13:23:38 +00:00
|
|
|
if (!ata_port_is_frozen(qc->ap)) {
|
2008-06-10 09:28:05 +00:00
|
|
|
tmp = atapi_eh_request_sense(qc->dev,
|
|
|
|
qc->scsicmd->sense_buffer,
|
2022-02-15 18:49:26 +00:00
|
|
|
qc->result_tf.error >> 4);
|
2016-04-04 09:44:01 +00:00
|
|
|
if (!tmp)
|
2006-11-21 01:40:51 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
2016-04-04 09:44:01 +00:00
|
|
|
else
|
2006-11-21 01:40:51 +00:00
|
|
|
qc->err_mask |= tmp;
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 09:44:01 +00:00
|
|
|
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
|
2021-04-15 22:08:11 +00:00
|
|
|
enum scsi_disposition ret = scsi_check_sense(qc->scsicmd);
|
2016-04-04 09:44:01 +00:00
|
|
|
/*
|
2018-05-09 00:28:08 +00:00
|
|
|
* SUCCESS here means that the sense code could be
|
2016-04-04 09:44:01 +00:00
|
|
|
* evaluated and should be passed to the upper layers
|
|
|
|
* for correct evaluation.
|
2018-05-09 00:28:08 +00:00
|
|
|
* FAILED means the sense code could not be interpreted
|
2016-04-04 09:44:01 +00:00
|
|
|
* and the device would need to be reset.
|
|
|
|
* NEEDS_RETRY and ADD_TO_MLQUEUE means that the
|
|
|
|
* command would need to be retried.
|
|
|
|
*/
|
|
|
|
if (ret == NEEDS_RETRY || ret == ADD_TO_MLQUEUE) {
|
|
|
|
qc->flags |= ATA_QCFLAG_RETRY;
|
|
|
|
qc->err_mask |= AC_ERR_OTHER;
|
|
|
|
} else if (ret != SUCCESS) {
|
|
|
|
qc->err_mask |= AC_ERR_HSM;
|
|
|
|
}
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
static int ata_eh_categorize_error(unsigned int eflags, unsigned int err_mask,
|
|
|
|
int *xfer_ok)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-11-27 10:28:59 +00:00
|
|
|
int base = 0;
|
|
|
|
|
|
|
|
if (!(eflags & ATA_EFLAG_DUBIOUS_XFER))
|
|
|
|
*xfer_ok = 1;
|
|
|
|
|
|
|
|
if (!*xfer_ok)
|
2008-01-02 16:21:14 +00:00
|
|
|
base = ATA_ECAT_DUBIOUS_NONE;
|
2007-11-27 10:28:59 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
if (err_mask & AC_ERR_ATA_BUS)
|
2007-11-27 10:28:59 +00:00
|
|
|
return base + ATA_ECAT_ATA_BUS;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
if (err_mask & AC_ERR_TIMEOUT)
|
2007-11-27 10:28:59 +00:00
|
|
|
return base + ATA_ECAT_TOUT_HSM;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
if (eflags & ATA_EFLAG_IS_IO) {
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
if (err_mask & AC_ERR_HSM)
|
2007-11-27 10:28:59 +00:00
|
|
|
return base + ATA_ECAT_TOUT_HSM;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
if ((err_mask &
|
|
|
|
(AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV)
|
2007-11-27 10:28:59 +00:00
|
|
|
return base + ATA_ECAT_UNK_DEV;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
struct speed_down_verdict_arg {
|
2006-05-15 11:58:22 +00:00
|
|
|
u64 since;
|
2007-11-27 10:28:59 +00:00
|
|
|
int xfer_ok;
|
2007-11-27 10:28:56 +00:00
|
|
|
int nr_errors[ATA_ECAT_NR];
|
2006-05-15 11:58:22 +00:00
|
|
|
};
|
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
struct speed_down_verdict_arg *arg = void_arg;
|
2007-11-27 10:28:59 +00:00
|
|
|
int cat;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2010-05-25 19:31:38 +00:00
|
|
|
if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since))
|
2006-05-15 11:58:22 +00:00
|
|
|
return -1;
|
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,
|
|
|
|
&arg->xfer_ok);
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
arg->nr_errors[cat]++;
|
2007-11-27 10:28:59 +00:00
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
* ata_eh_speed_down_verdict - Determine speed down verdict
|
2006-05-15 11:58:22 +00:00
|
|
|
* @dev: Device of interest
|
|
|
|
*
|
|
|
|
* This function examines error ring of @dev and determines
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
* whether NCQ needs to be turned off, transfer speed should be
|
|
|
|
* stepped down, or falling back to PIO is necessary.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
2007-11-27 10:28:56 +00:00
|
|
|
* ECAT_ATA_BUS : ATA_BUS error for any command
|
|
|
|
*
|
|
|
|
* ECAT_TOUT_HSM : TIMEOUT for any command or HSM violation for
|
|
|
|
* IO commands
|
|
|
|
*
|
|
|
|
* ECAT_UNK_DEV : Unknown DEV error for IO commands
|
|
|
|
*
|
2007-11-27 10:28:59 +00:00
|
|
|
* ECAT_DUBIOUS_* : Identical to above three but occurred while
|
|
|
|
* data transfer hasn't been verified.
|
|
|
|
*
|
2007-11-27 10:28:56 +00:00
|
|
|
* Verdicts are
|
|
|
|
*
|
|
|
|
* NCQ_OFF : Turn off NCQ.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
2007-11-27 10:28:56 +00:00
|
|
|
* SPEED_DOWN : Speed down transfer speed but don't fall back
|
|
|
|
* to PIO.
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
*
|
2007-11-27 10:28:56 +00:00
|
|
|
* FALLBACK_TO_PIO : Fall back to PIO.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
2007-11-27 10:28:56 +00:00
|
|
|
* Even if multiple verdicts are returned, only one action is
|
2007-11-27 10:28:59 +00:00
|
|
|
* taken per error. An action triggered by non-DUBIOUS errors
|
|
|
|
* clears ering, while one triggered by DUBIOUS_* errors doesn't.
|
|
|
|
* This is to expedite speed down decisions right after device is
|
|
|
|
* initially configured.
|
|
|
|
*
|
2017-02-27 22:29:56 +00:00
|
|
|
* The following are speed down rules. #1 and #2 deal with
|
2007-11-27 10:28:59 +00:00
|
|
|
* DUBIOUS errors.
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
*
|
2007-11-27 10:28:59 +00:00
|
|
|
* 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors
|
|
|
|
* occurred during last 5 mins, SPEED_DOWN and FALLBACK_TO_PIO.
|
|
|
|
*
|
|
|
|
* 2. If more than one DUBIOUS_TOUT_HSM or DUBIOUS_UNK_DEV errors
|
|
|
|
* occurred during last 5 mins, NCQ_OFF.
|
|
|
|
*
|
|
|
|
* 3. If more than 8 ATA_BUS, TOUT_HSM or UNK_DEV errors
|
2011-03-31 01:57:33 +00:00
|
|
|
* occurred during last 5 mins, FALLBACK_TO_PIO
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
*
|
2007-11-27 10:28:59 +00:00
|
|
|
* 4. If more than 3 TOUT_HSM or UNK_DEV errors occurred
|
2007-11-27 10:28:56 +00:00
|
|
|
* during last 10 mins, NCQ_OFF.
|
|
|
|
*
|
2007-11-27 10:28:59 +00:00
|
|
|
* 5. If more than 3 ATA_BUS or TOUT_HSM errors, or more than 6
|
2007-11-27 10:28:56 +00:00
|
|
|
* UNK_DEV errors occurred during last 10 mins, SPEED_DOWN.
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
*
|
2006-05-15 11:58:22 +00:00
|
|
|
* LOCKING:
|
|
|
|
* Inherited from caller.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
* OR of ATA_EH_SPDN_* flags.
|
2006-05-15 11:58:22 +00:00
|
|
|
*/
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
const u64 j5mins = 5LLU * 60 * HZ, j10mins = 10LLU * 60 * HZ;
|
|
|
|
u64 j64 = get_jiffies_64();
|
|
|
|
struct speed_down_verdict_arg arg;
|
|
|
|
unsigned int verdict = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
/* scan past 5 mins of error history */
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
memset(&arg, 0, sizeof(arg));
|
2007-11-27 10:28:56 +00:00
|
|
|
arg.since = j64 - min(j64, j5mins);
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
if (arg.nr_errors[ATA_ECAT_DUBIOUS_ATA_BUS] +
|
|
|
|
arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] > 1)
|
|
|
|
verdict |= ATA_EH_SPDN_SPEED_DOWN |
|
|
|
|
ATA_EH_SPDN_FALLBACK_TO_PIO | ATA_EH_SPDN_KEEP_ERRORS;
|
|
|
|
|
|
|
|
if (arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] +
|
|
|
|
arg.nr_errors[ATA_ECAT_DUBIOUS_UNK_DEV] > 1)
|
|
|
|
verdict |= ATA_EH_SPDN_NCQ_OFF | ATA_EH_SPDN_KEEP_ERRORS;
|
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
if (arg.nr_errors[ATA_ECAT_ATA_BUS] +
|
|
|
|
arg.nr_errors[ATA_ECAT_TOUT_HSM] +
|
2007-11-27 10:28:57 +00:00
|
|
|
arg.nr_errors[ATA_ECAT_UNK_DEV] > 6)
|
2007-11-27 10:28:56 +00:00
|
|
|
verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
/* scan past 10 mins of error history */
|
2006-05-15 11:58:22 +00:00
|
|
|
memset(&arg, 0, sizeof(arg));
|
2007-11-27 10:28:56 +00:00
|
|
|
arg.since = j64 - min(j64, j10mins);
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-11-27 10:28:56 +00:00
|
|
|
if (arg.nr_errors[ATA_ECAT_TOUT_HSM] +
|
|
|
|
arg.nr_errors[ATA_ECAT_UNK_DEV] > 3)
|
|
|
|
verdict |= ATA_EH_SPDN_NCQ_OFF;
|
|
|
|
|
|
|
|
if (arg.nr_errors[ATA_ECAT_ATA_BUS] +
|
|
|
|
arg.nr_errors[ATA_ECAT_TOUT_HSM] > 3 ||
|
2007-11-27 10:28:57 +00:00
|
|
|
arg.nr_errors[ATA_ECAT_UNK_DEV] > 6)
|
2007-11-27 10:28:56 +00:00
|
|
|
verdict |= ATA_EH_SPDN_SPEED_DOWN;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
return verdict;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_speed_down - record error and speed down if necessary
|
|
|
|
* @dev: Failed device
|
2007-11-27 10:28:56 +00:00
|
|
|
* @eflags: mask of ATA_EFLAG_* flags
|
2006-05-15 11:58:22 +00:00
|
|
|
* @err_mask: err_mask of the error
|
|
|
|
*
|
|
|
|
* Record error and examine error history to determine whether
|
|
|
|
* adjusting transmission speed is necessary. It also sets
|
|
|
|
* transmission limits appropriately if such adjustment is
|
|
|
|
* necessary.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
* Determined recovery action.
|
2006-05-15 11:58:22 +00:00
|
|
|
*/
|
2007-11-27 10:28:56 +00:00
|
|
|
static unsigned int ata_eh_speed_down(struct ata_device *dev,
|
|
|
|
unsigned int eflags, unsigned int err_mask)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
struct ata_link *link = ata_dev_phys_link(dev);
|
2007-11-27 10:28:59 +00:00
|
|
|
int xfer_ok = 0;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
unsigned int verdict;
|
|
|
|
unsigned int action = 0;
|
|
|
|
|
|
|
|
/* don't bother if Cat-0 error */
|
2007-11-27 10:28:59 +00:00
|
|
|
if (ata_eh_categorize_error(eflags, err_mask, &xfer_ok) == 0)
|
2006-05-15 11:58:22 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* record error and determine whether speed down is necessary */
|
2007-11-27 10:28:56 +00:00
|
|
|
ata_ering_record(&dev->ering, eflags, err_mask);
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
verdict = ata_eh_speed_down_verdict(dev);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
/* turn off NCQ? */
|
2023-06-04 23:16:32 +00:00
|
|
|
if ((verdict & ATA_EH_SPDN_NCQ_OFF) && ata_ncq_enabled(dev)) {
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
dev->flags |= ATA_DFLAG_NCQ_OFF;
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev, "NCQ disabled due to excessive errors\n");
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
/* speed down? */
|
|
|
|
if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
|
|
|
|
/* speed down SATA link speed if possible */
|
2009-01-29 11:31:33 +00:00
|
|
|
if (sata_down_spd_limit(link, 0) == 0) {
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
/* lower transfer mode */
|
|
|
|
if (dev->spdn_cnt < 2) {
|
|
|
|
static const int dma_dnxfer_sel[] =
|
|
|
|
{ ATA_DNXFER_DMA, ATA_DNXFER_40C };
|
|
|
|
static const int pio_dnxfer_sel[] =
|
|
|
|
{ ATA_DNXFER_PIO, ATA_DNXFER_FORCE_PIO0 };
|
|
|
|
int sel;
|
|
|
|
|
|
|
|
if (dev->xfer_shift != ATA_SHIFT_PIO)
|
|
|
|
sel = dma_dnxfer_sel[dev->spdn_cnt];
|
|
|
|
else
|
|
|
|
sel = pio_dnxfer_sel[dev->spdn_cnt];
|
|
|
|
|
|
|
|
dev->spdn_cnt++;
|
|
|
|
|
|
|
|
if (ata_down_xfermask_limit(dev, sel) == 0) {
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fall back to PIO? Slowing down to PIO is meaningless for
|
2007-11-27 10:28:57 +00:00
|
|
|
* SATA ATA devices. Consider it only for PATA and SATAPI.
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
*/
|
|
|
|
if ((verdict & ATA_EH_SPDN_FALLBACK_TO_PIO) && (dev->spdn_cnt >= 2) &&
|
2007-11-27 10:28:57 +00:00
|
|
|
(link->ap->cbl != ATA_CBL_SATA || dev->class == ATA_DEV_ATAPI) &&
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
(dev->xfer_shift != ATA_SHIFT_PIO)) {
|
|
|
|
if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) {
|
|
|
|
dev->spdn_cnt = 0;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
action |= ATA_EH_RESET;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
return 0;
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
done:
|
|
|
|
/* device has been slowed down, blow error history */
|
2007-11-27 10:28:59 +00:00
|
|
|
if (!(verdict & ATA_EH_SPDN_KEEP_ERRORS))
|
|
|
|
ata_ering_clear(&dev->ering);
|
libata: put some intelligence into EH speed down sequence
The current EH speed down code is more of a proof that the EH
framework is capable of adjusting transfer speed in response to error.
This patch puts some intelligence into EH speed down sequence. The
rules are..
* If there have been more than three timeout, HSM violation or
unclassified DEV errors for known supported commands during last 10
mins, NCQ is turned off.
* If there have been more than three timeout or HSM violation for known
supported command, transfer mode is slowed down. If DMA is active,
it is first slowered by one grade (e.g. UDMA133->100). If that
doesn't help, it's slowered to 40c limit (UDMA33). If PIO is
active, it's slowered by one grade first. If that doesn't help,
PIO0 is forced. Note that this rule does not change transfer mode.
DMA is never degraded into PIO by this rule.
* If there have been more than ten ATA bus, timeout, HSM violation or
unclassified device errors for known supported commands && speeding
down DMA mode didn't help, the device is forced into PIO mode. Note
that this rule is considered only for PATA devices and is pretty
difficult to trigger.
One error can only trigger one rule at a time. After a rule is
triggered, error history is cleared such that the next speed down
happens only after some number of errors are accumulated. This makes
sense because now speed down is done in bigger stride.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-02-02 07:22:31 +00:00
|
|
|
return action;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2012-05-02 19:22:52 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_worth_retry - analyze error and decide whether to retry
|
|
|
|
* @qc: qc to possibly retry
|
|
|
|
*
|
|
|
|
* Look at the cause of the error and decide if a retry
|
|
|
|
* might be useful or not. We don't want to retry media errors
|
|
|
|
* because the drive itself has probably already taken 10-30 seconds
|
|
|
|
* doing its own internal retries before reporting the failure.
|
|
|
|
*/
|
|
|
|
static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc)
|
|
|
|
{
|
2012-12-13 03:26:58 +00:00
|
|
|
if (qc->err_mask & AC_ERR_MEDIA)
|
2012-05-02 19:22:52 +00:00
|
|
|
return 0; /* don't retry media errors */
|
|
|
|
if (qc->flags & ATA_QCFLAG_IO)
|
|
|
|
return 1; /* otherwise retry anything from fs stack */
|
|
|
|
if (qc->err_mask & AC_ERR_INVALID)
|
|
|
|
return 0; /* don't retry these */
|
|
|
|
return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */
|
|
|
|
}
|
|
|
|
|
2018-05-09 00:28:11 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_quiet - check if we need to be quiet about a command error
|
|
|
|
* @qc: qc to check
|
|
|
|
*
|
|
|
|
* Look at the qc flags anbd its scsi command request flags to determine
|
|
|
|
* if we need to be quiet about the command failure.
|
|
|
|
*/
|
|
|
|
static inline bool ata_eh_quiet(struct ata_queued_cmd *qc)
|
|
|
|
{
|
2021-08-09 23:03:10 +00:00
|
|
|
if (qc->scsicmd && scsi_cmd_to_rq(qc->scsicmd)->rq_flags & RQF_QUIET)
|
2018-05-09 00:28:11 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_QUIET;
|
|
|
|
return qc->flags & ATA_QCFLAG_QUIET;
|
|
|
|
}
|
|
|
|
|
scsi: ata: libata: Handle completion of CDL commands using policy 0xD
A CDL timeout for policy 0xF is defined as a NCQ error, just with a CDL
specific sk/asc/ascq in the sense data. Therefore, the existing code in
libata does not need to be modified to handle a policy 0xF CDL timeout.
For Command Duration Limits policy 0xD:
The device shall complete the command without error with the additional
sense code set to DATA CURRENTLY UNAVAILABLE.
Since a CDL timeout for policy 0xD is not an error, we cannot use the NCQ
Command Error log (10h).
Instead, we need to read the Sense Data for Successful NCQ Commands log
(0Fh).
In the success case, just like in the error case, we cannot simply read a
log page from the interrupt handler itself, since reading a log page
involves sending a READ LOG DMA EXT or READ LOG EXT command.
Therefore, we add a new EH action ATA_EH_GET_SUCCESS_SENSE. When a command
completes without error, and when the ATA_SENSE bit is set, this new action
is set as pending, and EH is scheduled.
This way, similar to the NCQ error case, the log page will be read from EH
context.
An alternative would have been to add a new kthread or workqueue to handle
this. However, extending EH can be done with minimal changes and avoids the
need to synchronize a new kthread/workqueue with EH.
Co-developed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-20-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:52 +00:00
|
|
|
static int ata_eh_read_sense_success_non_ncq(struct ata_link *link)
|
|
|
|
{
|
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_queued_cmd *qc;
|
|
|
|
|
|
|
|
qc = __ata_qc_from_tag(ap, link->active_tag);
|
|
|
|
if (!qc)
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
|
|
|
!(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) ||
|
|
|
|
qc->err_mask)
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
if (!ata_eh_request_sense(qc))
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we have sense data, call scsi_check_sense() in order to set the
|
|
|
|
* correct SCSI ML byte (if any). No point in checking the return value,
|
|
|
|
* since the command has already completed successfully.
|
|
|
|
*/
|
|
|
|
scsi_check_sense(qc->scsicmd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ata_eh_get_success_sense(struct ata_link *link)
|
|
|
|
{
|
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
|
|
|
struct ata_device *dev = link->device;
|
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_queued_cmd *qc;
|
|
|
|
int tag, ret = 0;
|
|
|
|
|
|
|
|
if (!(ehc->i.dev_action[dev->devno] & ATA_EH_GET_SUCCESS_SENSE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* if frozen, we can't do much */
|
|
|
|
if (ata_port_is_frozen(ap)) {
|
|
|
|
ata_dev_warn(dev,
|
|
|
|
"successful sense data available but port frozen\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the link has sactive set, then we have outstanding NCQ commands
|
|
|
|
* and have to read the Successful NCQ Commands log to get the sense
|
|
|
|
* data. Otherwise, we are dealing with a non-NCQ command and use
|
|
|
|
* request sense ext command to retrieve the sense data.
|
|
|
|
*/
|
|
|
|
if (link->sactive)
|
|
|
|
ret = ata_eh_read_sense_success_ncq_log(link);
|
|
|
|
else
|
|
|
|
ret = ata_eh_read_sense_success_non_ncq(link);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE);
|
|
|
|
return;
|
|
|
|
|
|
|
|
out:
|
|
|
|
/*
|
|
|
|
* If we failed to get sense data for a successful command that ought to
|
|
|
|
* have sense data, we cannot simply return BLK_STS_OK to user space.
|
|
|
|
* This is because we can't know if the sense data that we couldn't get
|
|
|
|
* was actually "DATA CURRENTLY UNAVAILABLE". Reporting such a command
|
|
|
|
* as success to user space would result in a silent data corruption.
|
|
|
|
* Thus, add a bogus ABORTED_COMMAND sense data to such commands, such
|
|
|
|
* that SCSI will report these commands as BLK_STS_IOERR to user space.
|
|
|
|
*/
|
|
|
|
ata_qc_for_each_raw(ap, qc, tag) {
|
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
|
|
|
!(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) ||
|
|
|
|
qc->err_mask ||
|
|
|
|
ata_dev_phys_link(qc->dev) != link)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* We managed to get sense for this success command, skip. */
|
|
|
|
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* This success command did not have any sense data, skip. */
|
|
|
|
if (!(qc->result_tf.status & ATA_SENSE))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* This success command had sense data, but we failed to get. */
|
|
|
|
ata_scsi_set_sense(dev, qc->scsicmd, ABORTED_COMMAND, 0, 0);
|
|
|
|
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
|
|
|
}
|
|
|
|
ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE);
|
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/**
|
2007-08-06 09:36:24 +00:00
|
|
|
* ata_eh_link_autopsy - analyze error and determine recovery action
|
|
|
|
* @link: host link to perform autopsy on
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
2007-08-06 09:36:23 +00:00
|
|
|
* Analyze why @link failed and determine which recovery actions
|
|
|
|
* are needed. This function also sets more detailed AC_ERR_*
|
|
|
|
* values and fills sense data for ATAPI CHECK SENSE.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
2007-08-06 09:36:24 +00:00
|
|
|
static void ata_eh_link_autopsy(struct ata_link *link)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2007-10-31 01:17:05 +00:00
|
|
|
struct ata_device *dev;
|
2007-11-27 10:28:56 +00:00
|
|
|
unsigned int all_err_mask = 0, eflags = 0;
|
2018-05-09 00:28:11 +00:00
|
|
|
int tag, nr_failed = 0, nr_quiet = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
u32 serror;
|
|
|
|
int rc;
|
|
|
|
|
2006-07-03 07:07:26 +00:00
|
|
|
if (ehc->i.flags & ATA_EHI_NO_AUTOPSY)
|
|
|
|
return;
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/* obtain and analyze SError */
|
2007-08-06 09:36:23 +00:00
|
|
|
rc = sata_scr_read(link, SCR_ERROR, &serror);
|
2006-05-15 11:58:22 +00:00
|
|
|
if (rc == 0) {
|
|
|
|
ehc->i.serror |= serror;
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_analyze_serror(link);
|
2007-07-16 05:29:41 +00:00
|
|
|
} else if (rc != -EOPNOTSUPP) {
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
/* SError read failed, force reset and probing */
|
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.probe_mask |= ATA_ALL_DEVICES;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action |= ATA_EH_RESET;
|
2007-07-16 05:29:41 +00:00
|
|
|
ehc->i.err_mask |= AC_ERR_OTHER;
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2006-05-15 12:03:46 +00:00
|
|
|
/* analyze NCQ failure */
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_analyze_ncq_error(link);
|
2006-05-15 12:03:46 +00:00
|
|
|
|
scsi: ata: libata: Handle completion of CDL commands using policy 0xD
A CDL timeout for policy 0xF is defined as a NCQ error, just with a CDL
specific sk/asc/ascq in the sense data. Therefore, the existing code in
libata does not need to be modified to handle a policy 0xF CDL timeout.
For Command Duration Limits policy 0xD:
The device shall complete the command without error with the additional
sense code set to DATA CURRENTLY UNAVAILABLE.
Since a CDL timeout for policy 0xD is not an error, we cannot use the NCQ
Command Error log (10h).
Instead, we need to read the Sense Data for Successful NCQ Commands log
(0Fh).
In the success case, just like in the error case, we cannot simply read a
log page from the interrupt handler itself, since reading a log page
involves sending a READ LOG DMA EXT or READ LOG EXT command.
Therefore, we add a new EH action ATA_EH_GET_SUCCESS_SENSE. When a command
completes without error, and when the ATA_SENSE bit is set, this new action
is set as pending, and EH is scheduled.
This way, similar to the NCQ error case, the log page will be read from EH
context.
An alternative would have been to add a new kthread or workqueue to handle
this. However, extending EH can be done with minimal changes and avoids the
need to synchronize a new kthread/workqueue with EH.
Co-developed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-20-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:52 +00:00
|
|
|
/*
|
|
|
|
* Check if this was a successful command that simply needs sense data.
|
|
|
|
* Since the sense data is not part of the completion, we need to fetch
|
|
|
|
* it using an additional command. Since this can't be done from irq
|
|
|
|
* context, the sense data for successful commands are fetched by EH.
|
|
|
|
*/
|
|
|
|
ata_eh_get_success_sense(link);
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/* any real error trumps AC_ERR_OTHER */
|
|
|
|
if (ehc->i.err_mask & ~AC_ERR_OTHER)
|
|
|
|
ehc->i.err_mask &= ~AC_ERR_OTHER;
|
|
|
|
|
|
|
|
all_err_mask |= ehc->i.err_mask;
|
|
|
|
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each_raw(ap, qc, tag) {
|
2022-12-29 16:59:57 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
ata: libata: fix commands incorrectly not getting retried during NCQ error
A NCQ error means that the device has aborted processing of all active
commands.
To get the single NCQ command that caused the NCQ error, host software has
to read the NCQ error log, which also takes the device out of error state.
When the device encounters a NCQ error, we receive an error interrupt from
the HBA, and call ata_do_link_abort() to mark all outstanding commands on
the link as ATA_QCFLAG_FAILED (which means that these commands are owned
by libata EH), and then call ata_qc_complete() on them.
ata_qc_complete() will call fill_result_tf() for all commands marked as
ATA_QCFLAG_FAILED.
The taskfile is simply the latest status/error as seen from the device's
perspective. The taskfile will have ATA_ERR set in the status field and
ATA_ABORTED set in the error field.
When we fill the current taskfile values for all outstanding commands,
that means that qc->result_tf will have ATA_ERR set for all commands
owned by libata EH.
When ata_eh_link_autopsy() later analyzes all commands owned by libata EH,
it will call ata_eh_analyze_tf(), which will check if qc->result_tf has
ATA_ERR set, if it does, it will set qc->err_mask (which marks the command
as an error).
When ata_eh_finish() later calls __ata_qc_complete() on all commands owned
by libata EH, it will call qc->complete_fn() (ata_scsi_qc_complete()),
ata_scsi_qc_complete() will call ata_gen_ata_sense() to generate sense
data if qc->err_mask is set.
This means that we will generate sense data for commands that should not
have any sense data set. Having sense data set for the non-failed commands
will cause SCSI to finish these commands instead of retrying them.
While this incorrect behavior has existed for a long time, this first
became a problem once we started reading the correct taskfile register in
commit 4ba09d202657 ("ata: libahci: read correct status and error field
for NCQ commands").
Before this commit, NCQ commands would read the taskfile values received
from the last non-NCQ command completion, which most likely did not have
ATA_ERR set, since the last non-NCQ command was most likely not an error.
Fix this by changing ata_eh_analyze_ncq_error() to mark all non-failed
commands as ATA_QCFLAG_RETRY, and change the loop in ata_eh_link_autopsy()
to skip commands marked as ATA_QCFLAG_RETRY.
While at it, make sure that we clear ATA_ERR and any error bits for all
commands except the actual command that caused the NCQ error, so that no
other libata code will be able to misinterpret these commands as errors.
Fixes: 4ba09d202657 ("ata: libahci: read correct status and error field for NCQ commands")
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-11-14 17:21:59 +00:00
|
|
|
qc->flags & ATA_QCFLAG_RETRY ||
|
scsi: ata: libata: Handle completion of CDL commands using policy 0xD
A CDL timeout for policy 0xF is defined as a NCQ error, just with a CDL
specific sk/asc/ascq in the sense data. Therefore, the existing code in
libata does not need to be modified to handle a policy 0xF CDL timeout.
For Command Duration Limits policy 0xD:
The device shall complete the command without error with the additional
sense code set to DATA CURRENTLY UNAVAILABLE.
Since a CDL timeout for policy 0xD is not an error, we cannot use the NCQ
Command Error log (10h).
Instead, we need to read the Sense Data for Successful NCQ Commands log
(0Fh).
In the success case, just like in the error case, we cannot simply read a
log page from the interrupt handler itself, since reading a log page
involves sending a READ LOG DMA EXT or READ LOG EXT command.
Therefore, we add a new EH action ATA_EH_GET_SUCCESS_SENSE. When a command
completes without error, and when the ATA_SENSE bit is set, this new action
is set as pending, and EH is scheduled.
This way, similar to the NCQ error case, the log page will be read from EH
context.
An alternative would have been to add a new kthread or workqueue to handle
this. However, extending EH can be done with minimal changes and avoids the
need to synchronize a new kthread/workqueue with EH.
Co-developed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-20-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:52 +00:00
|
|
|
qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD ||
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
ata_dev_phys_link(qc->dev) != link)
|
2006-05-15 11:58:22 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* inherit upper level err_mask */
|
|
|
|
qc->err_mask |= ehc->i.err_mask;
|
|
|
|
|
|
|
|
/* analyze TF */
|
2022-09-16 12:28:37 +00:00
|
|
|
ehc->i.action |= ata_eh_analyze_tf(qc);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
/* DEV errors are probably spurious in case of ATA_BUS error */
|
|
|
|
if (qc->err_mask & AC_ERR_ATA_BUS)
|
|
|
|
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_MEDIA |
|
|
|
|
AC_ERR_INVALID);
|
|
|
|
|
|
|
|
/* any real error trumps unknown error */
|
|
|
|
if (qc->err_mask & ~AC_ERR_OTHER)
|
|
|
|
qc->err_mask &= ~AC_ERR_OTHER;
|
|
|
|
|
2018-05-09 00:28:12 +00:00
|
|
|
/*
|
|
|
|
* SENSE_VALID trumps dev/unknown error and revalidation. Upper
|
|
|
|
* layers will determine whether the command is worth retrying
|
|
|
|
* based on the sense data and device class/type. Otherwise,
|
|
|
|
* determine directly if the command is worth retrying using its
|
|
|
|
* error mask and flags.
|
|
|
|
*/
|
2007-10-26 07:12:41 +00:00
|
|
|
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
|
2006-05-15 11:58:22 +00:00
|
|
|
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
|
2018-05-09 00:28:12 +00:00
|
|
|
else if (ata_eh_worth_retry(qc))
|
2008-03-27 10:14:24 +00:00
|
|
|
qc->flags |= ATA_QCFLAG_RETRY;
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/* accumulate error info */
|
2006-07-08 11:17:26 +00:00
|
|
|
ehc->i.dev = qc->dev;
|
2006-05-15 11:58:22 +00:00
|
|
|
all_err_mask |= qc->err_mask;
|
|
|
|
if (qc->flags & ATA_QCFLAG_IO)
|
2007-11-27 10:28:56 +00:00
|
|
|
eflags |= ATA_EFLAG_IS_IO;
|
2015-03-27 15:46:38 +00:00
|
|
|
trace_ata_eh_link_autopsy_qc(qc);
|
2018-05-09 00:28:11 +00:00
|
|
|
|
|
|
|
/* Count quiet errors */
|
|
|
|
if (ata_eh_quiet(qc))
|
|
|
|
nr_quiet++;
|
|
|
|
nr_failed++;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 00:28:11 +00:00
|
|
|
/* If all failed commands requested silence, then be quiet */
|
|
|
|
if (nr_quiet == nr_failed)
|
|
|
|
ehc->i.flags |= ATA_EHI_QUIET;
|
|
|
|
|
2006-05-16 03:58:24 +00:00
|
|
|
/* enforce default EH actions */
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(ap) ||
|
2006-05-16 03:58:24 +00:00
|
|
|
all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action |= ATA_EH_RESET;
|
2007-11-27 10:28:56 +00:00
|
|
|
else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) ||
|
|
|
|
(!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV)))
|
2006-07-08 11:17:26 +00:00
|
|
|
ehc->i.action |= ATA_EH_REVALIDATE;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-10-31 01:17:05 +00:00
|
|
|
/* If we have offending qcs and the associated failed device,
|
|
|
|
* perform per-dev EH action only on the offending device.
|
|
|
|
*/
|
2006-07-08 11:17:26 +00:00
|
|
|
if (ehc->i.dev) {
|
|
|
|
ehc->i.dev_action[ehc->i.dev->devno] |=
|
|
|
|
ehc->i.action & ATA_EH_PERDEV_MASK;
|
|
|
|
ehc->i.action &= ~ATA_EH_PERDEV_MASK;
|
2006-06-19 09:27:23 +00:00
|
|
|
}
|
|
|
|
|
2008-01-10 04:41:23 +00:00
|
|
|
/* propagate timeout to host link */
|
|
|
|
if ((all_err_mask & AC_ERR_TIMEOUT) && !ata_is_host_link(link))
|
|
|
|
ap->link.eh_context.i.err_mask |= AC_ERR_TIMEOUT;
|
|
|
|
|
|
|
|
/* record error and consider speeding down */
|
2007-10-31 01:17:05 +00:00
|
|
|
dev = ehc->i.dev;
|
2008-01-10 04:41:23 +00:00
|
|
|
if (!dev && ((ata_link_max_devices(link) == 1 &&
|
|
|
|
ata_dev_enabled(link->device))))
|
|
|
|
dev = link->device;
|
2007-10-31 01:17:05 +00:00
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
if (dev) {
|
|
|
|
if (dev->flags & ATA_DFLAG_DUBIOUS_XFER)
|
|
|
|
eflags |= ATA_EFLAG_DUBIOUS_XFER;
|
2007-11-27 10:28:56 +00:00
|
|
|
ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask);
|
2017-11-02 11:01:07 +00:00
|
|
|
trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask);
|
2007-11-27 10:28:59 +00:00
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2007-08-06 09:36:24 +00:00
|
|
|
* ata_eh_autopsy - analyze error and determine recovery action
|
|
|
|
* @ap: host port to perform autopsy on
|
|
|
|
*
|
|
|
|
* Analyze all links of @ap and determine why they failed and
|
|
|
|
* which recovery actions are needed.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_autopsy(struct ata_port *ap)
|
2007-08-06 09:36:24 +00:00
|
|
|
{
|
|
|
|
struct ata_link *link;
|
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE)
|
2007-08-06 09:36:24 +00:00
|
|
|
ata_eh_link_autopsy(link);
|
2008-01-10 04:41:23 +00:00
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
/* Handle the frigging slave link. Autopsy is done similarly
|
|
|
|
* but actions and flags are transferred over to the master
|
|
|
|
* link and handled from there.
|
|
|
|
*/
|
|
|
|
if (ap->slave_link) {
|
|
|
|
struct ata_eh_context *mehc = &ap->link.eh_context;
|
|
|
|
struct ata_eh_context *sehc = &ap->slave_link->eh_context;
|
|
|
|
|
2008-10-21 05:26:39 +00:00
|
|
|
/* transfer control flags from master to slave */
|
|
|
|
sehc->i.flags |= mehc->i.flags & ATA_EHI_TO_SLAVE_MASK;
|
|
|
|
|
|
|
|
/* perform autopsy on the slave link */
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
ata_eh_link_autopsy(ap->slave_link);
|
|
|
|
|
2008-10-21 05:26:39 +00:00
|
|
|
/* transfer actions from slave to master and clear slave */
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
|
|
|
|
mehc->i.action |= sehc->i.action;
|
|
|
|
mehc->i.dev_action[1] |= sehc->i.dev_action[1];
|
|
|
|
mehc->i.flags |= sehc->i.flags;
|
|
|
|
ata_eh_done(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
|
|
|
|
}
|
|
|
|
|
2008-01-10 04:41:23 +00:00
|
|
|
/* Autopsy of fanout ports can affect host link autopsy.
|
|
|
|
* Perform host link autopsy last.
|
|
|
|
*/
|
2008-04-07 13:47:22 +00:00
|
|
|
if (sata_pmp_attached(ap))
|
2008-01-10 04:41:23 +00:00
|
|
|
ata_eh_link_autopsy(&ap->link);
|
2007-08-06 09:36:24 +00:00
|
|
|
}
|
|
|
|
|
2009-07-15 02:43:39 +00:00
|
|
|
/**
|
2021-12-21 07:20:36 +00:00
|
|
|
* ata_get_cmd_name - get name for ATA command
|
|
|
|
* @command: ATA command code to get name for
|
2009-07-15 02:43:39 +00:00
|
|
|
*
|
2021-12-21 07:20:36 +00:00
|
|
|
* Return a textual name of the given command or "unknown"
|
2009-07-15 02:43:39 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None
|
|
|
|
*/
|
2021-12-21 07:20:36 +00:00
|
|
|
const char *ata_get_cmd_name(u8 command)
|
2009-07-15 02:43:39 +00:00
|
|
|
{
|
|
|
|
#ifdef CONFIG_ATA_VERBOSE_ERROR
|
|
|
|
static const struct
|
|
|
|
{
|
|
|
|
u8 command;
|
|
|
|
const char *text;
|
|
|
|
} cmd_descr[] = {
|
|
|
|
{ ATA_CMD_DEV_RESET, "DEVICE RESET" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_CHK_POWER, "CHECK POWER MODE" },
|
|
|
|
{ ATA_CMD_STANDBY, "STANDBY" },
|
|
|
|
{ ATA_CMD_IDLE, "IDLE" },
|
|
|
|
{ ATA_CMD_EDD, "EXECUTE DEVICE DIAGNOSTIC" },
|
|
|
|
{ ATA_CMD_DOWNLOAD_MICRO, "DOWNLOAD MICROCODE" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_DOWNLOAD_MICRO_DMA, "DOWNLOAD MICROCODE DMA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_NOP, "NOP" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_FLUSH, "FLUSH CACHE" },
|
|
|
|
{ ATA_CMD_FLUSH_EXT, "FLUSH CACHE EXT" },
|
|
|
|
{ ATA_CMD_ID_ATA, "IDENTIFY DEVICE" },
|
|
|
|
{ ATA_CMD_ID_ATAPI, "IDENTIFY PACKET DEVICE" },
|
|
|
|
{ ATA_CMD_SERVICE, "SERVICE" },
|
|
|
|
{ ATA_CMD_READ, "READ DMA" },
|
|
|
|
{ ATA_CMD_READ_EXT, "READ DMA EXT" },
|
|
|
|
{ ATA_CMD_READ_QUEUED, "READ DMA QUEUED" },
|
|
|
|
{ ATA_CMD_READ_STREAM_EXT, "READ STREAM EXT" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_READ_STREAM_DMA_EXT, "READ STREAM DMA EXT" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_WRITE, "WRITE DMA" },
|
|
|
|
{ ATA_CMD_WRITE_EXT, "WRITE DMA EXT" },
|
|
|
|
{ ATA_CMD_WRITE_QUEUED, "WRITE DMA QUEUED EXT" },
|
|
|
|
{ ATA_CMD_WRITE_STREAM_EXT, "WRITE STREAM EXT" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_WRITE_STREAM_DMA_EXT, "WRITE STREAM DMA EXT" },
|
|
|
|
{ ATA_CMD_WRITE_FUA_EXT, "WRITE DMA FUA EXT" },
|
|
|
|
{ ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" },
|
|
|
|
{ ATA_CMD_FPDMA_READ, "READ FPDMA QUEUED" },
|
|
|
|
{ ATA_CMD_FPDMA_WRITE, "WRITE FPDMA QUEUED" },
|
2022-08-11 17:29:53 +00:00
|
|
|
{ ATA_CMD_NCQ_NON_DATA, "NCQ NON-DATA" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_FPDMA_SEND, "SEND FPDMA QUEUED" },
|
|
|
|
{ ATA_CMD_FPDMA_RECV, "RECEIVE FPDMA QUEUED" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_PIO_READ, "READ SECTOR(S)" },
|
|
|
|
{ ATA_CMD_PIO_READ_EXT, "READ SECTOR(S) EXT" },
|
|
|
|
{ ATA_CMD_PIO_WRITE, "WRITE SECTOR(S)" },
|
|
|
|
{ ATA_CMD_PIO_WRITE_EXT, "WRITE SECTOR(S) EXT" },
|
|
|
|
{ ATA_CMD_READ_MULTI, "READ MULTIPLE" },
|
|
|
|
{ ATA_CMD_READ_MULTI_EXT, "READ MULTIPLE EXT" },
|
|
|
|
{ ATA_CMD_WRITE_MULTI, "WRITE MULTIPLE" },
|
|
|
|
{ ATA_CMD_WRITE_MULTI_EXT, "WRITE MULTIPLE EXT" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_WRITE_MULTI_FUA_EXT, "WRITE MULTIPLE FUA EXT" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_SET_FEATURES, "SET FEATURES" },
|
|
|
|
{ ATA_CMD_SET_MULTI, "SET MULTIPLE MODE" },
|
|
|
|
{ ATA_CMD_VERIFY, "READ VERIFY SECTOR(S)" },
|
|
|
|
{ ATA_CMD_VERIFY_EXT, "READ VERIFY SECTOR(S) EXT" },
|
|
|
|
{ ATA_CMD_WRITE_UNCORR_EXT, "WRITE UNCORRECTABLE EXT" },
|
|
|
|
{ ATA_CMD_STANDBYNOW1, "STANDBY IMMEDIATE" },
|
|
|
|
{ ATA_CMD_IDLEIMMEDIATE, "IDLE IMMEDIATE" },
|
|
|
|
{ ATA_CMD_SLEEP, "SLEEP" },
|
|
|
|
{ ATA_CMD_INIT_DEV_PARAMS, "INITIALIZE DEVICE PARAMETERS" },
|
|
|
|
{ ATA_CMD_READ_NATIVE_MAX, "READ NATIVE MAX ADDRESS" },
|
|
|
|
{ ATA_CMD_READ_NATIVE_MAX_EXT, "READ NATIVE MAX ADDRESS EXT" },
|
|
|
|
{ ATA_CMD_SET_MAX, "SET MAX ADDRESS" },
|
|
|
|
{ ATA_CMD_SET_MAX_EXT, "SET MAX ADDRESS EXT" },
|
|
|
|
{ ATA_CMD_READ_LOG_EXT, "READ LOG EXT" },
|
|
|
|
{ ATA_CMD_WRITE_LOG_EXT, "WRITE LOG EXT" },
|
|
|
|
{ ATA_CMD_READ_LOG_DMA_EXT, "READ LOG DMA EXT" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_WRITE_LOG_DMA_EXT, "WRITE LOG DMA EXT" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_TRUSTED_NONDATA, "TRUSTED NON-DATA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_TRUSTED_RCV, "TRUSTED RECEIVE" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_TRUSTED_RCV_DMA, "TRUSTED RECEIVE DMA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_TRUSTED_SND, "TRUSTED SEND" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_TRUSTED_SND_DMA, "TRUSTED SEND DMA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_PMP_READ, "READ BUFFER" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_PMP_READ_DMA, "READ BUFFER DMA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_PMP_WRITE, "WRITE BUFFER" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_PMP_WRITE_DMA, "WRITE BUFFER DMA" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_CONF_OVERLAY, "DEVICE CONFIGURATION OVERLAY" },
|
|
|
|
{ ATA_CMD_SEC_SET_PASS, "SECURITY SET PASSWORD" },
|
|
|
|
{ ATA_CMD_SEC_UNLOCK, "SECURITY UNLOCK" },
|
|
|
|
{ ATA_CMD_SEC_ERASE_PREP, "SECURITY ERASE PREPARE" },
|
|
|
|
{ ATA_CMD_SEC_ERASE_UNIT, "SECURITY ERASE UNIT" },
|
|
|
|
{ ATA_CMD_SEC_FREEZE_LOCK, "SECURITY FREEZE LOCK" },
|
|
|
|
{ ATA_CMD_SEC_DISABLE_PASS, "SECURITY DISABLE PASSWORD" },
|
|
|
|
{ ATA_CMD_CONFIG_STREAM, "CONFIGURE STREAM" },
|
|
|
|
{ ATA_CMD_SMART, "SMART" },
|
|
|
|
{ ATA_CMD_MEDIA_LOCK, "DOOR LOCK" },
|
|
|
|
{ ATA_CMD_MEDIA_UNLOCK, "DOOR UNLOCK" },
|
2010-07-05 06:45:20 +00:00
|
|
|
{ ATA_CMD_DSM, "DATA SET MANAGEMENT" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_CHK_MED_CRD_TYP, "CHECK MEDIA CARD TYPE" },
|
|
|
|
{ ATA_CMD_CFA_REQ_EXT_ERR, "CFA REQUEST EXTENDED ERROR" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_CFA_WRITE_NE, "CFA WRITE SECTORS WITHOUT ERASE" },
|
|
|
|
{ ATA_CMD_CFA_TRANS_SECT, "CFA TRANSLATE SECTOR" },
|
|
|
|
{ ATA_CMD_CFA_ERASE, "CFA ERASE SECTORS" },
|
2015-03-27 15:46:31 +00:00
|
|
|
{ ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" },
|
2013-10-22 01:26:30 +00:00
|
|
|
{ ATA_CMD_REQ_SENSE_DATA, "REQUEST SENSE DATA EXT" },
|
|
|
|
{ ATA_CMD_SANITIZE_DEVICE, "SANITIZE DEVICE" },
|
2016-04-25 10:45:52 +00:00
|
|
|
{ ATA_CMD_ZAC_MGMT_IN, "ZAC MANAGEMENT IN" },
|
2016-04-25 10:45:53 +00:00
|
|
|
{ ATA_CMD_ZAC_MGMT_OUT, "ZAC MANAGEMENT OUT" },
|
2009-07-15 02:43:39 +00:00
|
|
|
{ ATA_CMD_READ_LONG, "READ LONG (with retries)" },
|
|
|
|
{ ATA_CMD_READ_LONG_ONCE, "READ LONG (without retries)" },
|
|
|
|
{ ATA_CMD_WRITE_LONG, "WRITE LONG (with retries)" },
|
|
|
|
{ ATA_CMD_WRITE_LONG_ONCE, "WRITE LONG (without retries)" },
|
|
|
|
{ ATA_CMD_RESTORE, "RECALIBRATE" },
|
|
|
|
{ 0, NULL } /* terminate list */
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned int i;
|
|
|
|
for (i = 0; cmd_descr[i].text; i++)
|
|
|
|
if (cmd_descr[i].command == command)
|
|
|
|
return cmd_descr[i].text;
|
|
|
|
#endif
|
|
|
|
|
2021-12-21 07:20:36 +00:00
|
|
|
return "unknown";
|
2009-07-15 02:43:39 +00:00
|
|
|
}
|
2021-12-21 07:20:36 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_get_cmd_name);
|
2009-07-15 02:43:39 +00:00
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_link_report - report error handling to user
|
2007-08-06 09:36:23 +00:00
|
|
|
* @link: ATA link EH is going on
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* Report EH to user.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-08-06 09:36:24 +00:00
|
|
|
static void ata_eh_link_report(struct ata_link *link)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2006-05-15 11:58:22 +00:00
|
|
|
const char *frozen, *desc;
|
ata: libata-eh: Fix compilation warning in ata_eh_link_report()
The 6 bytes length of the tries_buf string in ata_eh_link_report() is
too short and results in a gcc compilation warning with W-!:
drivers/ata/libata-eh.c: In function ‘ata_eh_link_report’:
drivers/ata/libata-eh.c:2371:59: warning: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 4 [-Wformat-truncation=]
2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d",
| ^~
drivers/ata/libata-eh.c:2371:56: note: directive argument in the range [-2147483648, 4]
2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d",
| ^~~~~~
drivers/ata/libata-eh.c:2371:17: note: ‘snprintf’ output between 4 and 14 bytes into a destination of size 6
2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2372 | ap->eh_tries);
| ~~~~~~~~~~~~~
Avoid this warning by increasing the string size to 16B.
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-09-12 00:08:40 +00:00
|
|
|
char tries_buf[16] = "";
|
2006-05-15 11:58:22 +00:00
|
|
|
int tag, nr_failed = 0;
|
|
|
|
|
2007-10-09 05:57:56 +00:00
|
|
|
if (ehc->i.flags & ATA_EHI_QUIET)
|
|
|
|
return;
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
desc = NULL;
|
|
|
|
if (ehc->i.desc[0] != '\0')
|
|
|
|
desc = ehc->i.desc;
|
|
|
|
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each_raw(ap, qc, tag) {
|
2022-12-29 16:59:57 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
ata_dev_phys_link(qc->dev) != link ||
|
2007-10-26 07:19:26 +00:00
|
|
|
((qc->flags & ATA_QCFLAG_QUIET) &&
|
|
|
|
qc->err_mask == AC_ERR_DEV))
|
2006-05-15 11:58:22 +00:00
|
|
|
continue;
|
|
|
|
if (qc->flags & ATA_QCFLAG_SENSE_VALID && !qc->err_mask)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nr_failed++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nr_failed && !ehc->i.err_mask)
|
|
|
|
return;
|
|
|
|
|
|
|
|
frozen = "";
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(ap))
|
2006-05-15 11:58:22 +00:00
|
|
|
frozen = " frozen";
|
|
|
|
|
2007-08-18 04:28:49 +00:00
|
|
|
if (ap->eh_tries < ATA_EH_MAX_TRIES)
|
2013-10-29 19:01:46 +00:00
|
|
|
snprintf(tries_buf, sizeof(tries_buf), " t%d",
|
2007-08-18 04:28:49 +00:00
|
|
|
ap->eh_tries);
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
if (ehc->i.dev) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_err(ehc->i.dev, "exception Emask 0x%x "
|
|
|
|
"SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
|
|
|
|
ehc->i.err_mask, link->sactive, ehc->i.serror,
|
|
|
|
ehc->i.action, frozen, tries_buf);
|
2006-05-15 11:58:22 +00:00
|
|
|
if (desc)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_err(ehc->i.dev, "%s\n", desc);
|
2006-05-15 11:58:22 +00:00
|
|
|
} else {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link, "exception Emask 0x%x "
|
|
|
|
"SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
|
|
|
|
ehc->i.err_mask, link->sactive, ehc->i.serror,
|
|
|
|
ehc->i.action, frozen, tries_buf);
|
2006-05-15 11:58:22 +00:00
|
|
|
if (desc)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link, "%s\n", desc);
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2009-07-15 02:43:39 +00:00
|
|
|
#ifdef CONFIG_ATA_VERBOSE_ERROR
|
2007-10-02 15:22:02 +00:00
|
|
|
if (ehc->i.serror)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link,
|
2007-10-02 15:22:02 +00:00
|
|
|
"SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
|
|
|
|
ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
|
|
|
|
ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
|
|
|
|
ehc->i.serror & SERR_DATA ? "UnrecovData " : "",
|
|
|
|
ehc->i.serror & SERR_PERSISTENT ? "Persist " : "",
|
|
|
|
ehc->i.serror & SERR_PROTOCOL ? "Proto " : "",
|
|
|
|
ehc->i.serror & SERR_INTERNAL ? "HostInt " : "",
|
|
|
|
ehc->i.serror & SERR_PHYRDY_CHG ? "PHYRdyChg " : "",
|
|
|
|
ehc->i.serror & SERR_PHY_INT_ERR ? "PHYInt " : "",
|
|
|
|
ehc->i.serror & SERR_COMM_WAKE ? "CommWake " : "",
|
|
|
|
ehc->i.serror & SERR_10B_8B_ERR ? "10B8B " : "",
|
|
|
|
ehc->i.serror & SERR_DISPARITY ? "Dispar " : "",
|
|
|
|
ehc->i.serror & SERR_CRC ? "BadCRC " : "",
|
|
|
|
ehc->i.serror & SERR_HANDSHAKE ? "Handshk " : "",
|
|
|
|
ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "",
|
|
|
|
ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "",
|
|
|
|
ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "",
|
2007-10-19 10:42:56 +00:00
|
|
|
ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "");
|
2009-07-15 02:43:39 +00:00
|
|
|
#endif
|
2007-10-02 15:22:02 +00:00
|
|
|
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each_raw(ap, qc, tag) {
|
2006-11-14 13:36:12 +00:00
|
|
|
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
|
2007-11-28 14:16:09 +00:00
|
|
|
char data_buf[20] = "";
|
|
|
|
char cdb_buf[70] = "";
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2022-12-29 16:59:57 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
ata_dev_phys_link(qc->dev) != link || !qc->err_mask)
|
2006-05-15 11:58:22 +00:00
|
|
|
continue;
|
|
|
|
|
2007-11-28 14:16:09 +00:00
|
|
|
if (qc->dma_dir != DMA_NONE) {
|
|
|
|
static const char *dma_str[] = {
|
|
|
|
[DMA_BIDIRECTIONAL] = "bidi",
|
|
|
|
[DMA_TO_DEVICE] = "out",
|
|
|
|
[DMA_FROM_DEVICE] = "in",
|
|
|
|
};
|
2017-01-09 14:49:28 +00:00
|
|
|
const char *prot_str = NULL;
|
|
|
|
|
|
|
|
switch (qc->tf.protocol) {
|
|
|
|
case ATA_PROT_UNKNOWN:
|
|
|
|
prot_str = "unknown";
|
|
|
|
break;
|
|
|
|
case ATA_PROT_NODATA:
|
|
|
|
prot_str = "nodata";
|
|
|
|
break;
|
|
|
|
case ATA_PROT_PIO:
|
|
|
|
prot_str = "pio";
|
|
|
|
break;
|
|
|
|
case ATA_PROT_DMA:
|
|
|
|
prot_str = "dma";
|
|
|
|
break;
|
|
|
|
case ATA_PROT_NCQ:
|
|
|
|
prot_str = "ncq dma";
|
|
|
|
break;
|
|
|
|
case ATA_PROT_NCQ_NODATA:
|
|
|
|
prot_str = "ncq nodata";
|
|
|
|
break;
|
|
|
|
case ATAPI_PROT_NODATA:
|
|
|
|
prot_str = "nodata";
|
|
|
|
break;
|
|
|
|
case ATAPI_PROT_PIO:
|
|
|
|
prot_str = "pio";
|
|
|
|
break;
|
|
|
|
case ATAPI_PROT_DMA:
|
|
|
|
prot_str = "dma";
|
|
|
|
break;
|
|
|
|
}
|
2007-11-28 14:16:09 +00:00
|
|
|
snprintf(data_buf, sizeof(data_buf), " %s %u %s",
|
2017-01-09 14:49:28 +00:00
|
|
|
prot_str, qc->nbytes, dma_str[qc->dma_dir]);
|
2007-11-28 14:16:09 +00:00
|
|
|
}
|
|
|
|
|
2009-07-15 02:43:39 +00:00
|
|
|
if (ata_is_atapi(qc->tf.protocol)) {
|
2015-01-19 15:55:38 +00:00
|
|
|
const u8 *cdb = qc->cdb;
|
|
|
|
size_t cdb_len = qc->dev->cdb_len;
|
|
|
|
|
2015-01-08 06:43:45 +00:00
|
|
|
if (qc->scsicmd) {
|
|
|
|
cdb = qc->scsicmd->cmnd;
|
|
|
|
cdb_len = qc->scsicmd->cmd_len;
|
|
|
|
}
|
|
|
|
__scsi_format_command(cdb_buf, sizeof(cdb_buf),
|
|
|
|
cdb, cdb_len);
|
2021-12-21 07:20:36 +00:00
|
|
|
} else
|
|
|
|
ata_dev_err(qc->dev, "failed command: %s\n",
|
|
|
|
ata_get_cmd_name(cmd->command));
|
2007-11-28 14:16:09 +00:00
|
|
|
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_err(qc->dev,
|
2006-11-14 13:36:12 +00:00
|
|
|
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
2007-11-28 14:16:09 +00:00
|
|
|
"tag %d%s\n %s"
|
2006-11-14 13:36:12 +00:00
|
|
|
"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
2007-07-16 05:29:40 +00:00
|
|
|
"Emask 0x%x (%s)%s\n",
|
2006-11-14 13:36:12 +00:00
|
|
|
cmd->command, cmd->feature, cmd->nsect,
|
|
|
|
cmd->lbal, cmd->lbam, cmd->lbah,
|
|
|
|
cmd->hob_feature, cmd->hob_nsect,
|
|
|
|
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
|
2007-11-28 14:16:09 +00:00
|
|
|
cmd->device, qc->tag, data_buf, cdb_buf,
|
2022-02-15 18:49:26 +00:00
|
|
|
res->status, res->error, res->nsect,
|
2006-11-14 13:36:12 +00:00
|
|
|
res->lbal, res->lbam, res->lbah,
|
|
|
|
res->hob_feature, res->hob_nsect,
|
|
|
|
res->hob_lbal, res->hob_lbam, res->hob_lbah,
|
2007-07-16 05:29:40 +00:00
|
|
|
res->device, qc->err_mask, ata_err_string(qc->err_mask),
|
|
|
|
qc->err_mask & AC_ERR_NCQ ? " <F>" : "");
|
2007-10-02 15:22:02 +00:00
|
|
|
|
2009-07-15 02:43:39 +00:00
|
|
|
#ifdef CONFIG_ATA_VERBOSE_ERROR
|
2022-02-15 18:49:26 +00:00
|
|
|
if (res->status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
|
|
|
|
ATA_SENSE | ATA_ERR)) {
|
|
|
|
if (res->status & ATA_BUSY)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_err(qc->dev, "status: { Busy }\n");
|
2007-10-02 15:22:02 +00:00
|
|
|
else
|
2016-04-04 09:43:55 +00:00
|
|
|
ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
|
2022-02-15 18:49:26 +00:00
|
|
|
res->status & ATA_DRDY ? "DRDY " : "",
|
|
|
|
res->status & ATA_DF ? "DF " : "",
|
|
|
|
res->status & ATA_DRQ ? "DRQ " : "",
|
|
|
|
res->status & ATA_SENSE ? "SENSE " : "",
|
|
|
|
res->status & ATA_ERR ? "ERR " : "");
|
2007-10-02 15:22:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd->command != ATA_CMD_PACKET &&
|
2022-02-15 18:49:26 +00:00
|
|
|
(res->error & (ATA_ICRC | ATA_UNC | ATA_AMNF | ATA_IDNF |
|
|
|
|
ATA_ABORTED)))
|
2014-07-15 06:28:42 +00:00
|
|
|
ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
|
2022-02-15 18:49:26 +00:00
|
|
|
res->error & ATA_ICRC ? "ICRC " : "",
|
|
|
|
res->error & ATA_UNC ? "UNC " : "",
|
|
|
|
res->error & ATA_AMNF ? "AMNF " : "",
|
|
|
|
res->error & ATA_IDNF ? "IDNF " : "",
|
|
|
|
res->error & ATA_ABORTED ? "ABRT " : "");
|
2009-07-15 02:43:39 +00:00
|
|
|
#endif
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_report - report error handling to user
|
|
|
|
* @ap: ATA port to report EH about
|
|
|
|
*
|
|
|
|
* Report EH to user.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_report(struct ata_port *ap)
|
2007-08-06 09:36:24 +00:00
|
|
|
{
|
|
|
|
struct ata_link *link;
|
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, HOST_FIRST)
|
2007-08-06 09:36:24 +00:00
|
|
|
ata_eh_link_report(link);
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
unsigned int *classes, unsigned long deadline,
|
|
|
|
bool clear_classes)
|
2006-05-31 09:28:24 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *dev;
|
2006-05-31 09:28:24 +00:00
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (clear_classes)
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL)
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_UNKNOWN;
|
2006-05-31 09:28:24 +00:00
|
|
|
|
2008-05-18 16:15:08 +00:00
|
|
|
return reset(link, classes, deadline);
|
2006-05-31 09:28:24 +00:00
|
|
|
}
|
|
|
|
|
2011-08-09 19:25:50 +00:00
|
|
|
static int ata_eh_followup_srst_needed(struct ata_link *link, int rc)
|
2006-05-31 09:27:50 +00:00
|
|
|
{
|
2008-04-07 16:46:56 +00:00
|
|
|
if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
|
2007-09-23 04:14:12 +00:00
|
|
|
return 0;
|
2008-07-31 07:08:02 +00:00
|
|
|
if (rc == -EAGAIN)
|
|
|
|
return 1;
|
2008-04-07 13:47:22 +00:00
|
|
|
if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
|
2007-09-23 04:19:53 +00:00
|
|
|
return 1;
|
2006-05-31 09:27:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-23 04:14:12 +00:00
|
|
|
int ata_eh_reset(struct ata_link *link, int classify,
|
|
|
|
ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
|
|
|
|
ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-10-09 06:06:10 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
struct ata_link *slave = ap->slave_link;
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2009-07-26 14:21:01 +00:00
|
|
|
struct ata_eh_context *sehc = slave ? &slave->eh_context : NULL;
|
2006-05-31 09:27:50 +00:00
|
|
|
unsigned int *classes = ehc->classes;
|
2007-10-31 01:17:03 +00:00
|
|
|
unsigned int lflags = link->flags;
|
2006-07-03 07:07:26 +00:00
|
|
|
int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
|
2008-05-19 17:17:53 +00:00
|
|
|
int max_tries = 0, try = 0;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
struct ata_link *failed_link;
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *dev;
|
2007-10-31 01:17:03 +00:00
|
|
|
unsigned long deadline, now;
|
2006-05-15 11:58:22 +00:00
|
|
|
ata_reset_fn_t reset;
|
2007-10-09 06:06:10 +00:00
|
|
|
unsigned long flags;
|
2007-10-31 01:17:03 +00:00
|
|
|
u32 sstatus;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
int nr_unknown, rc;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
/*
|
|
|
|
* Prepare to reset
|
|
|
|
*/
|
2023-07-29 20:17:48 +00:00
|
|
|
while (ata_eh_reset_timeouts[max_tries] != UINT_MAX)
|
2008-05-19 17:17:53 +00:00
|
|
|
max_tries++;
|
2012-06-22 06:41:41 +00:00
|
|
|
if (link->flags & ATA_LFLAG_RST_ONCE)
|
|
|
|
max_tries = 1;
|
2008-08-13 11:19:09 +00:00
|
|
|
if (link->flags & ATA_LFLAG_NO_HRST)
|
|
|
|
hardreset = NULL;
|
|
|
|
if (link->flags & ATA_LFLAG_NO_SRST)
|
|
|
|
softreset = NULL;
|
2008-05-19 17:17:53 +00:00
|
|
|
|
2011-03-31 01:57:33 +00:00
|
|
|
/* make sure each reset attempt is at least COOL_DOWN apart */
|
2008-11-04 08:08:40 +00:00
|
|
|
if (ehc->i.flags & ATA_EHI_DID_RESET) {
|
|
|
|
now = jiffies;
|
|
|
|
WARN_ON(time_after(ehc->last_reset, now));
|
|
|
|
deadline = ata_deadline(ehc->last_reset,
|
|
|
|
ATA_EH_RESET_COOL_DOWN);
|
|
|
|
if (time_before(now, deadline))
|
|
|
|
schedule_timeout_uninterruptible(deadline - now);
|
|
|
|
}
|
2008-05-19 17:17:52 +00:00
|
|
|
|
2007-10-09 06:06:10 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
ap->pflags |= ATA_PFLAG_RESETTING;
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
2006-07-10 14:18:46 +00:00
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2007-10-29 07:41:09 +00:00
|
|
|
/* If we issue an SRST then an ATA drive (not ATAPI)
|
|
|
|
* may change configuration and be in PIO0 timing. If
|
|
|
|
* we do a hard reset (or are coming from power on)
|
|
|
|
* this is true for ATA or ATAPI. Until we've set a
|
|
|
|
* suitable controller mode we should not touch the
|
|
|
|
* bus as we may be talking too fast.
|
|
|
|
*/
|
|
|
|
dev->pio_mode = XFER_PIO_0;
|
2012-12-03 03:35:02 +00:00
|
|
|
dev->dma_mode = 0xff;
|
2007-10-29 07:41:09 +00:00
|
|
|
|
|
|
|
/* If the controller has a pio mode setup function
|
|
|
|
* then use it to set the chipset to rights. Don't
|
|
|
|
* touch the DMA setup as that will be dealt with when
|
|
|
|
* configuring devices.
|
|
|
|
*/
|
|
|
|
if (ap->ops->set_piomode)
|
|
|
|
ap->ops->set_piomode(ap, dev);
|
|
|
|
}
|
|
|
|
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
/* prefer hardreset */
|
2008-05-18 16:15:06 +00:00
|
|
|
reset = NULL;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action &= ~ATA_EH_RESET;
|
|
|
|
if (hardreset) {
|
|
|
|
reset = hardreset;
|
2008-07-31 07:07:04 +00:00
|
|
|
ehc->i.action |= ATA_EH_HARDRESET;
|
2008-01-30 09:18:26 +00:00
|
|
|
} else if (softreset) {
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
reset = softreset;
|
2008-07-31 07:07:04 +00:00
|
|
|
ehc->i.action |= ATA_EH_SOFTRESET;
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
}
|
2006-05-31 09:27:48 +00:00
|
|
|
|
|
|
|
if (prereset) {
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
unsigned long deadline = ata_deadline(jiffies,
|
|
|
|
ATA_EH_PRERESET_TIMEOUT);
|
|
|
|
|
|
|
|
if (slave) {
|
|
|
|
sehc->i.action &= ~ATA_EH_RESET;
|
|
|
|
sehc->i.action |= ehc->i.action;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = prereset(link, deadline);
|
|
|
|
|
|
|
|
/* If present, do prereset on slave link too. Reset
|
|
|
|
* is skipped iff both master and slave links report
|
|
|
|
* -ENOENT or clear ATA_EH_RESET.
|
|
|
|
*/
|
|
|
|
if (slave && (rc == 0 || rc == -ENOENT)) {
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
tmp = prereset(slave, deadline);
|
|
|
|
if (tmp != -ENOENT)
|
|
|
|
rc = tmp;
|
|
|
|
|
|
|
|
ehc->i.action |= sehc->i.action;
|
|
|
|
}
|
|
|
|
|
2006-05-31 09:27:48 +00:00
|
|
|
if (rc) {
|
2006-09-26 16:53:38 +00:00
|
|
|
if (rc == -ENOENT) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_dbg(link, "port disabled--ignoring\n");
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action &= ~ATA_EH_RESET;
|
2007-03-12 08:24:08 +00:00
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL)
|
2007-08-06 09:36:23 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_NONE;
|
2007-03-12 08:24:08 +00:00
|
|
|
|
|
|
|
rc = 0;
|
2006-09-26 16:53:38 +00:00
|
|
|
} else
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link,
|
|
|
|
"prereset failed (errno=%d)\n",
|
|
|
|
rc);
|
2007-07-16 05:29:41 +00:00
|
|
|
goto out;
|
2006-05-31 09:27:48 +00:00
|
|
|
}
|
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
/* prereset() might have cleared ATA_EH_RESET. If so,
|
2009-03-04 06:59:30 +00:00
|
|
|
* bang classes, thaw and return.
|
2008-05-18 16:15:06 +00:00
|
|
|
*/
|
|
|
|
if (reset && !(ehc->i.action & ATA_EH_RESET)) {
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL)
|
2008-05-18 16:15:06 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_NONE;
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(ap) && ata_is_host_link(link))
|
2009-03-04 06:59:30 +00:00
|
|
|
ata_eh_thaw_port(ap);
|
2008-05-18 16:15:06 +00:00
|
|
|
rc = 0;
|
|
|
|
goto out;
|
|
|
|
}
|
2006-05-31 09:27:48 +00:00
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
retry:
|
2008-05-18 16:15:06 +00:00
|
|
|
/*
|
|
|
|
* Perform reset
|
|
|
|
*/
|
2008-05-18 16:15:07 +00:00
|
|
|
if (ata_is_host_link(link))
|
|
|
|
ata_eh_freeze_port(ap);
|
|
|
|
|
2008-05-19 17:17:51 +00:00
|
|
|
deadline = ata_deadline(jiffies, ata_eh_reset_timeouts[try++]);
|
2007-02-02 07:50:52 +00:00
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
if (reset) {
|
|
|
|
if (verbose)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_info(link, "%s resetting link\n",
|
|
|
|
reset == softreset ? "soft" : "hard");
|
2008-05-18 16:15:06 +00:00
|
|
|
|
|
|
|
/* mark that this EH session started with reset */
|
2008-11-04 08:08:40 +00:00
|
|
|
ehc->last_reset = jiffies;
|
2021-12-21 07:20:29 +00:00
|
|
|
if (reset == hardreset) {
|
2008-05-18 16:15:06 +00:00
|
|
|
ehc->i.flags |= ATA_EHI_DID_HARDRESET;
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_link_hardreset_begin(link, classes, deadline);
|
|
|
|
} else {
|
2008-05-18 16:15:06 +00:00
|
|
|
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_link_softreset_begin(link, classes, deadline);
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
rc = ata_do_reset(link, reset, classes, deadline, true);
|
2021-12-21 07:20:29 +00:00
|
|
|
if (reset == hardreset)
|
|
|
|
trace_ata_link_hardreset_end(link, classes, rc);
|
|
|
|
else
|
|
|
|
trace_ata_link_softreset_end(link, classes, rc);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (rc && rc != -EAGAIN) {
|
|
|
|
failed_link = link;
|
2008-07-31 07:08:02 +00:00
|
|
|
goto fail;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* hardreset slave link if existent */
|
|
|
|
if (slave && reset == hardreset) {
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
if (verbose)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_info(slave, "hard resetting link\n");
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
|
|
|
|
ata_eh_about_to_do(slave, NULL, ATA_EH_RESET);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_slave_hardreset_begin(slave, classes,
|
|
|
|
deadline);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
tmp = ata_do_reset(slave, reset, classes, deadline,
|
|
|
|
false);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_slave_hardreset_end(slave, classes, tmp);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
switch (tmp) {
|
|
|
|
case -EAGAIN:
|
|
|
|
rc = -EAGAIN;
|
2021-04-20 20:11:29 +00:00
|
|
|
break;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
failed_link = slave;
|
|
|
|
rc = tmp;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
/* perform follow-up SRST if necessary */
|
2008-05-18 16:15:06 +00:00
|
|
|
if (reset == hardreset &&
|
2011-08-09 19:25:50 +00:00
|
|
|
ata_eh_followup_srst_needed(link, rc)) {
|
2008-05-18 16:15:06 +00:00
|
|
|
reset = softreset;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
if (!reset) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link,
|
|
|
|
"follow-up softreset required but no softreset available\n");
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
failed_link = link;
|
2008-05-18 16:15:06 +00:00
|
|
|
rc = -EINVAL;
|
|
|
|
goto fail;
|
|
|
|
}
|
2006-05-31 09:27:50 +00:00
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_link_softreset_begin(link, classes, deadline);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
rc = ata_do_reset(link, reset, classes, deadline, true);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_link_softreset_end(link, classes, rc);
|
2009-07-08 03:16:37 +00:00
|
|
|
if (rc) {
|
|
|
|
failed_link = link;
|
|
|
|
goto fail;
|
|
|
|
}
|
2006-05-31 09:27:50 +00:00
|
|
|
}
|
2008-05-18 16:15:06 +00:00
|
|
|
} else {
|
|
|
|
if (verbose)
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_info(link,
|
|
|
|
"no reset method available, skipping reset\n");
|
2008-05-18 16:15:06 +00:00
|
|
|
if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
|
|
|
|
lflags |= ATA_LFLAG_ASSUME_ATA;
|
2006-05-31 09:27:50 +00:00
|
|
|
}
|
|
|
|
|
2008-05-18 16:15:06 +00:00
|
|
|
/*
|
|
|
|
* Post-reset processing
|
|
|
|
*/
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2007-10-31 01:17:03 +00:00
|
|
|
/* After the reset, the device state is PIO 0 and the
|
|
|
|
* controller state is undefined. Reset also wakes up
|
|
|
|
* drives from sleeping mode.
|
|
|
|
*/
|
|
|
|
dev->pio_mode = XFER_PIO_0;
|
|
|
|
dev->flags &= ~ATA_DFLAG_SLEEPING;
|
2007-02-02 07:50:52 +00:00
|
|
|
|
2009-10-06 08:08:40 +00:00
|
|
|
if (ata_phys_link_offline(ata_dev_phys_link(dev)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* apply class override */
|
|
|
|
if (lflags & ATA_LFLAG_ASSUME_ATA)
|
|
|
|
classes[dev->devno] = ATA_DEV_ATA;
|
|
|
|
else if (lflags & ATA_LFLAG_ASSUME_SEMB)
|
|
|
|
classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 01:17:03 +00:00
|
|
|
/* record current link speed */
|
|
|
|
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0)
|
|
|
|
link->sata_spd = (sstatus >> 4) & 0xf;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (slave && sata_scr_read(slave, SCR_STATUS, &sstatus) == 0)
|
|
|
|
slave->sata_spd = (sstatus >> 4) & 0xf;
|
2007-07-16 05:29:40 +00:00
|
|
|
|
2008-05-18 16:15:07 +00:00
|
|
|
/* thaw the port */
|
|
|
|
if (ata_is_host_link(link))
|
|
|
|
ata_eh_thaw_port(ap);
|
|
|
|
|
2008-05-18 16:15:08 +00:00
|
|
|
/* postreset() should clear hardware SError. Although SError
|
|
|
|
* is cleared during link resume, clearing SError here is
|
|
|
|
* necessary as some PHYs raise hotplug events after SRST.
|
|
|
|
* This introduces race condition where hotplug occurs between
|
|
|
|
* reset and here. This race is mediated by cross checking
|
|
|
|
* link onlineness and classification result later.
|
|
|
|
*/
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (postreset) {
|
2007-10-31 01:17:03 +00:00
|
|
|
postreset(link, classes);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_link_postreset(link, classes, rc);
|
|
|
|
if (slave) {
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
postreset(slave, classes);
|
2021-12-21 07:20:29 +00:00
|
|
|
trace_ata_slave_postreset(slave, classes, rc);
|
|
|
|
}
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
}
|
2006-05-31 09:27:23 +00:00
|
|
|
|
ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset()
ata_scsi_port_error_handler() starts off by clearing ATA_PFLAG_EH_PENDING,
before calling ap->ops->error_handler() (without holding the ap->lock).
If an error IRQ is received while ap->ops->error_handler() is running,
the irq handler will set ATA_PFLAG_EH_PENDING.
Once ap->ops->error_handler() returns, ata_scsi_port_error_handler()
checks if ATA_PFLAG_EH_PENDING is set, and if it is, another iteration
of ATA EH is performed.
The problem is that ATA_PFLAG_EH_PENDING is not only cleared by
ata_scsi_port_error_handler(), it is also cleared by ata_eh_reset().
ata_eh_reset() is called by ap->ops->error_handler(). This additional
clearing done by ata_eh_reset() breaks the whole retry logic in
ata_scsi_port_error_handler(). Thus, if an error IRQ is received while
ap->ops->error_handler() is running, the port will currently remain
frozen and will never get re-enabled.
The additional clearing in ata_eh_reset() was introduced in commit
1e641060c4b5 ("libata: clear eh_info on reset completion").
Looking at the original error report:
https://marc.info/?l=linux-ide&m=124765325828495&w=2
We can see the following happening:
[ 1.074659] ata3: XXX port freeze
[ 1.074700] ata3: XXX hardresetting link, stopping engine
[ 1.074746] ata3: XXX flipping SControl
[ 1.411471] ata3: XXX irq_stat=400040 CONN|PHY
[ 1.411475] ata3: XXX port freeze
[ 1.420049] ata3: XXX starting engine
[ 1.420096] ata3: XXX rc=0, class=1
[ 1.420142] ata3: XXX clearing IRQs for thawing
[ 1.420188] ata3: XXX port thawed
[ 1.420234] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
We are not supposed to be able to receive an error IRQ while the port is
frozen (PxIE is set to 0, i.e. all IRQs for the port are disabled).
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) states:
"Each bit location can be thought of as reporting a '1' if the virtual
"interrupt line" for that port is indicating it wishes to generate an
interrupt. That is, if a port has one or more interrupt status bit set,
and the enables for those status bits are set, then this bit shall be set."
Additionally, AHCI state P:ComInit clearly shows that the state machine
will only jump to P:ComInitSetIS (which sets IS.IPS(x) to '1'), if PxIE.PCE
is set to '1'. In our case, PxIE is set to 0, so IS.IPS(x) won't get set.
So IS.IPS(x) only gets set if PxIS and PxIE is set.
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) also states:
"The bits in this register are read/write clear. It is set by the level of
the virtual interrupt line being a set, and cleared by a write of '1' from
the software."
So if IS.IPS(x) is set, you need to explicitly clear it by writing a 1 to
IS.IPS(x) for that port.
Since PxIE is cleared, the only way to get an interrupt while the port is
frozen, is if IS.IPS(x) is set, and the only way IS.IPS(x) can be set when
the port is frozen, is if it was set before the port was frozen.
However, since commit 737dd811a3db ("ata: libahci: clear pending interrupt
status"), we clear both PxIS and IS.IPS(x) after freezing the port, but
before the COMRESET, so the problem that commit 1e641060c4b5 ("libata:
clear eh_info on reset completion") fixed can no longer happen.
Thus, revert commit 1e641060c4b5 ("libata: clear eh_info on reset
completion"), so that the retry logic in ata_scsi_port_error_handler()
works once again. (The retry logic is still needed, since we can still
get an error IRQ _after_ the port has been thawed, but before
ata_scsi_port_error_handler() takes the ap->lock in order to check
if ATA_PFLAG_EH_PENDING is set.)
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-09-13 22:19:16 +00:00
|
|
|
/* clear cached SError */
|
2008-05-18 16:15:08 +00:00
|
|
|
spin_lock_irqsave(link->ap->lock, flags);
|
ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset()
ata_scsi_port_error_handler() starts off by clearing ATA_PFLAG_EH_PENDING,
before calling ap->ops->error_handler() (without holding the ap->lock).
If an error IRQ is received while ap->ops->error_handler() is running,
the irq handler will set ATA_PFLAG_EH_PENDING.
Once ap->ops->error_handler() returns, ata_scsi_port_error_handler()
checks if ATA_PFLAG_EH_PENDING is set, and if it is, another iteration
of ATA EH is performed.
The problem is that ATA_PFLAG_EH_PENDING is not only cleared by
ata_scsi_port_error_handler(), it is also cleared by ata_eh_reset().
ata_eh_reset() is called by ap->ops->error_handler(). This additional
clearing done by ata_eh_reset() breaks the whole retry logic in
ata_scsi_port_error_handler(). Thus, if an error IRQ is received while
ap->ops->error_handler() is running, the port will currently remain
frozen and will never get re-enabled.
The additional clearing in ata_eh_reset() was introduced in commit
1e641060c4b5 ("libata: clear eh_info on reset completion").
Looking at the original error report:
https://marc.info/?l=linux-ide&m=124765325828495&w=2
We can see the following happening:
[ 1.074659] ata3: XXX port freeze
[ 1.074700] ata3: XXX hardresetting link, stopping engine
[ 1.074746] ata3: XXX flipping SControl
[ 1.411471] ata3: XXX irq_stat=400040 CONN|PHY
[ 1.411475] ata3: XXX port freeze
[ 1.420049] ata3: XXX starting engine
[ 1.420096] ata3: XXX rc=0, class=1
[ 1.420142] ata3: XXX clearing IRQs for thawing
[ 1.420188] ata3: XXX port thawed
[ 1.420234] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
We are not supposed to be able to receive an error IRQ while the port is
frozen (PxIE is set to 0, i.e. all IRQs for the port are disabled).
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) states:
"Each bit location can be thought of as reporting a '1' if the virtual
"interrupt line" for that port is indicating it wishes to generate an
interrupt. That is, if a port has one or more interrupt status bit set,
and the enables for those status bits are set, then this bit shall be set."
Additionally, AHCI state P:ComInit clearly shows that the state machine
will only jump to P:ComInitSetIS (which sets IS.IPS(x) to '1'), if PxIE.PCE
is set to '1'. In our case, PxIE is set to 0, so IS.IPS(x) won't get set.
So IS.IPS(x) only gets set if PxIS and PxIE is set.
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) also states:
"The bits in this register are read/write clear. It is set by the level of
the virtual interrupt line being a set, and cleared by a write of '1' from
the software."
So if IS.IPS(x) is set, you need to explicitly clear it by writing a 1 to
IS.IPS(x) for that port.
Since PxIE is cleared, the only way to get an interrupt while the port is
frozen, is if IS.IPS(x) is set, and the only way IS.IPS(x) can be set when
the port is frozen, is if it was set before the port was frozen.
However, since commit 737dd811a3db ("ata: libahci: clear pending interrupt
status"), we clear both PxIS and IS.IPS(x) after freezing the port, but
before the COMRESET, so the problem that commit 1e641060c4b5 ("libata:
clear eh_info on reset completion") fixed can no longer happen.
Thus, revert commit 1e641060c4b5 ("libata: clear eh_info on reset
completion"), so that the retry logic in ata_scsi_port_error_handler()
works once again. (The retry logic is still needed, since we can still
get an error IRQ _after_ the port has been thawed, but before
ata_scsi_port_error_handler() takes the ap->lock in order to check
if ATA_PFLAG_EH_PENDING is set.)
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-09-13 22:19:16 +00:00
|
|
|
link->eh_info.serror = 0;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (slave)
|
ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset()
ata_scsi_port_error_handler() starts off by clearing ATA_PFLAG_EH_PENDING,
before calling ap->ops->error_handler() (without holding the ap->lock).
If an error IRQ is received while ap->ops->error_handler() is running,
the irq handler will set ATA_PFLAG_EH_PENDING.
Once ap->ops->error_handler() returns, ata_scsi_port_error_handler()
checks if ATA_PFLAG_EH_PENDING is set, and if it is, another iteration
of ATA EH is performed.
The problem is that ATA_PFLAG_EH_PENDING is not only cleared by
ata_scsi_port_error_handler(), it is also cleared by ata_eh_reset().
ata_eh_reset() is called by ap->ops->error_handler(). This additional
clearing done by ata_eh_reset() breaks the whole retry logic in
ata_scsi_port_error_handler(). Thus, if an error IRQ is received while
ap->ops->error_handler() is running, the port will currently remain
frozen and will never get re-enabled.
The additional clearing in ata_eh_reset() was introduced in commit
1e641060c4b5 ("libata: clear eh_info on reset completion").
Looking at the original error report:
https://marc.info/?l=linux-ide&m=124765325828495&w=2
We can see the following happening:
[ 1.074659] ata3: XXX port freeze
[ 1.074700] ata3: XXX hardresetting link, stopping engine
[ 1.074746] ata3: XXX flipping SControl
[ 1.411471] ata3: XXX irq_stat=400040 CONN|PHY
[ 1.411475] ata3: XXX port freeze
[ 1.420049] ata3: XXX starting engine
[ 1.420096] ata3: XXX rc=0, class=1
[ 1.420142] ata3: XXX clearing IRQs for thawing
[ 1.420188] ata3: XXX port thawed
[ 1.420234] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
We are not supposed to be able to receive an error IRQ while the port is
frozen (PxIE is set to 0, i.e. all IRQs for the port are disabled).
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) states:
"Each bit location can be thought of as reporting a '1' if the virtual
"interrupt line" for that port is indicating it wishes to generate an
interrupt. That is, if a port has one or more interrupt status bit set,
and the enables for those status bits are set, then this bit shall be set."
Additionally, AHCI state P:ComInit clearly shows that the state machine
will only jump to P:ComInitSetIS (which sets IS.IPS(x) to '1'), if PxIE.PCE
is set to '1'. In our case, PxIE is set to 0, so IS.IPS(x) won't get set.
So IS.IPS(x) only gets set if PxIS and PxIE is set.
AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) also states:
"The bits in this register are read/write clear. It is set by the level of
the virtual interrupt line being a set, and cleared by a write of '1' from
the software."
So if IS.IPS(x) is set, you need to explicitly clear it by writing a 1 to
IS.IPS(x) for that port.
Since PxIE is cleared, the only way to get an interrupt while the port is
frozen, is if IS.IPS(x) is set, and the only way IS.IPS(x) can be set when
the port is frozen, is if it was set before the port was frozen.
However, since commit 737dd811a3db ("ata: libahci: clear pending interrupt
status"), we clear both PxIS and IS.IPS(x) after freezing the port, but
before the COMRESET, so the problem that commit 1e641060c4b5 ("libata:
clear eh_info on reset completion") fixed can no longer happen.
Thus, revert commit 1e641060c4b5 ("libata: clear eh_info on reset
completion"), so that the retry logic in ata_scsi_port_error_handler()
works once again. (The retry logic is still needed, since we can still
get an error IRQ _after_ the port has been thawed, but before
ata_scsi_port_error_handler() takes the ap->lock in order to check
if ATA_PFLAG_EH_PENDING is set.)
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-09-13 22:19:16 +00:00
|
|
|
slave->eh_info.serror = 0;
|
2008-05-18 16:15:08 +00:00
|
|
|
spin_unlock_irqrestore(link->ap->lock, flags);
|
|
|
|
|
2009-10-06 08:08:40 +00:00
|
|
|
/*
|
|
|
|
* Make sure onlineness and classification result correspond.
|
2008-05-18 16:15:08 +00:00
|
|
|
* Hotplug could have happened during reset and some
|
|
|
|
* controllers fail to wait while a drive is spinning up after
|
|
|
|
* being hotplugged causing misdetection. By cross checking
|
2009-10-06 08:08:40 +00:00
|
|
|
* link on/offlineness and classification result, those
|
|
|
|
* conditions can be reliably detected and retried.
|
2008-05-18 16:15:08 +00:00
|
|
|
*/
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
nr_unknown = 0;
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2009-10-06 08:08:40 +00:00
|
|
|
if (ata_phys_link_online(ata_dev_phys_link(dev))) {
|
|
|
|
if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_dbg(dev, "link online but device misclassified\n");
|
2009-10-06 08:08:40 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_NONE;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
nr_unknown++;
|
2009-10-06 08:08:40 +00:00
|
|
|
}
|
|
|
|
} else if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
|
|
|
|
if (ata_class_enabled(classes[dev->devno]))
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_dbg(dev,
|
|
|
|
"link offline, clearing class %d to NONE\n",
|
|
|
|
classes[dev->devno]);
|
2009-10-06 08:08:40 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_NONE;
|
|
|
|
} else if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_dbg(dev,
|
|
|
|
"link status unknown, clearing UNKNOWN to NONE\n");
|
2009-10-06 08:08:40 +00:00
|
|
|
classes[dev->devno] = ATA_DEV_NONE;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
}
|
2008-05-18 16:15:08 +00:00
|
|
|
}
|
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (classify && nr_unknown) {
|
2008-05-18 16:15:08 +00:00
|
|
|
if (try < max_tries) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_warn(link,
|
|
|
|
"link online but %d devices misclassified, retrying\n",
|
|
|
|
nr_unknown);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
failed_link = link;
|
2008-05-18 16:15:08 +00:00
|
|
|
rc = -EAGAIN;
|
|
|
|
goto fail;
|
|
|
|
}
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_warn(link,
|
|
|
|
"link online but %d devices misclassified, "
|
|
|
|
"device detection might fail\n", nr_unknown);
|
2008-05-18 16:15:08 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 01:17:03 +00:00
|
|
|
/* reset successful, schedule revalidation */
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ata_eh_done(link, NULL, ATA_EH_RESET);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (slave)
|
|
|
|
ata_eh_done(slave, NULL, ATA_EH_RESET);
|
2010-09-01 15:50:06 +00:00
|
|
|
ehc->last_reset = jiffies; /* update to completion time */
|
2007-10-31 01:17:03 +00:00
|
|
|
ehc->i.action |= ATA_EH_REVALIDATE;
|
2010-09-01 15:50:06 +00:00
|
|
|
link->lpm_policy = ATA_LPM_UNKNOWN; /* reset LPM state */
|
2007-09-23 04:14:12 +00:00
|
|
|
|
2007-10-31 01:17:03 +00:00
|
|
|
rc = 0;
|
2007-07-16 05:29:41 +00:00
|
|
|
out:
|
|
|
|
/* clear hotplug flag */
|
|
|
|
ehc->i.flags &= ~ATA_EHI_HOTPLUGGED;
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (slave)
|
|
|
|
sehc->i.flags &= ~ATA_EHI_HOTPLUGGED;
|
2007-10-09 06:06:10 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
ap->pflags &= ~ATA_PFLAG_RESETTING;
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
return rc;
|
2007-10-31 01:17:03 +00:00
|
|
|
|
|
|
|
fail:
|
2008-04-07 13:47:20 +00:00
|
|
|
/* if SCR isn't accessible on a fan-out port, PMP needs to be reset */
|
|
|
|
if (!ata_is_host_link(link) &&
|
|
|
|
sata_scr_read(link, SCR_STATUS, &sstatus))
|
|
|
|
rc = -ERESTART;
|
|
|
|
|
2011-10-20 00:17:02 +00:00
|
|
|
if (try >= max_tries) {
|
2011-05-25 10:23:56 +00:00
|
|
|
/*
|
|
|
|
* Thaw host port even if reset failed, so that the port
|
|
|
|
* can be retried on the next phy event. This risks
|
|
|
|
* repeated EH runs but seems to be a better tradeoff than
|
|
|
|
* shutting down a port after a botched hotplug attempt.
|
|
|
|
*/
|
|
|
|
if (ata_is_host_link(link))
|
|
|
|
ata_eh_thaw_port(ap);
|
2007-10-31 01:17:03 +00:00
|
|
|
goto out;
|
2011-05-25 10:23:56 +00:00
|
|
|
}
|
2007-10-31 01:17:03 +00:00
|
|
|
|
|
|
|
now = jiffies;
|
|
|
|
if (time_before(now, deadline)) {
|
|
|
|
unsigned long delta = deadline - now;
|
|
|
|
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_warn(failed_link,
|
2008-05-19 17:17:52 +00:00
|
|
|
"reset failed (errno=%d), retrying in %u secs\n",
|
|
|
|
rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000));
|
2007-10-31 01:17:03 +00:00
|
|
|
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
ata_eh_release(ap);
|
2007-10-31 01:17:03 +00:00
|
|
|
while (delta)
|
|
|
|
delta = schedule_timeout_uninterruptible(delta);
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
ata_eh_acquire(ap);
|
2007-10-31 01:17:03 +00:00
|
|
|
}
|
|
|
|
|
2011-10-20 00:17:02 +00:00
|
|
|
/*
|
|
|
|
* While disks spinup behind PMP, some controllers fail sending SRST.
|
|
|
|
* They need to be reset - as well as the PMP - before retrying.
|
|
|
|
*/
|
|
|
|
if (rc == -ERESTART) {
|
|
|
|
if (ata_is_host_link(link))
|
|
|
|
ata_eh_thaw_port(ap);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (try == max_tries - 1) {
|
2009-01-29 11:31:33 +00:00
|
|
|
sata_down_spd_limit(link, 0);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (slave)
|
2009-01-29 11:31:33 +00:00
|
|
|
sata_down_spd_limit(slave, 0);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
} else if (rc == -EPIPE)
|
2009-01-29 11:31:33 +00:00
|
|
|
sata_down_spd_limit(failed_link, 0);
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
|
2007-10-31 01:17:03 +00:00
|
|
|
if (hardreset)
|
|
|
|
reset = hardreset;
|
|
|
|
goto retry;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2008-09-21 09:54:08 +00:00
|
|
|
static inline void ata_eh_pull_park_action(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
struct ata_link *link;
|
|
|
|
struct ata_device *dev;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function can be thought of as an extended version of
|
|
|
|
* ata_eh_about_to_do() specially crafted to accommodate the
|
|
|
|
* requirements of ATA_EH_PARK handling. Since the EH thread
|
|
|
|
* does not leave the do {} while () loop in ata_eh_recover as
|
|
|
|
* long as the timeout for a park request to *one* device on
|
|
|
|
* the port has not expired, and since we still want to pick
|
|
|
|
* up park requests to other devices on the same port or
|
|
|
|
* timeout updates for the same device, we have to pull
|
|
|
|
* ATA_EH_PARK actions from eh_info into eh_context.i
|
|
|
|
* ourselves at the beginning of each pass over the loop.
|
|
|
|
*
|
|
|
|
* Additionally, all write accesses to &ap->park_req_pending
|
2013-11-14 22:32:02 +00:00
|
|
|
* through reinit_completion() (see below) or complete_all()
|
2008-09-21 09:54:08 +00:00
|
|
|
* (see ata_scsi_park_store()) are protected by the host lock.
|
|
|
|
* As a result we have that park_req_pending.done is zero on
|
|
|
|
* exit from this function, i.e. when ATA_EH_PARK actions for
|
|
|
|
* *all* devices on port ap have been pulled into the
|
|
|
|
* respective eh_context structs. If, and only if,
|
|
|
|
* park_req_pending.done is non-zero by the time we reach
|
|
|
|
* wait_for_completion_timeout(), another ATA_EH_PARK action
|
|
|
|
* has been scheduled for at least one of the devices on port
|
|
|
|
* ap and we have to cycle over the do {} while () loop in
|
|
|
|
* ata_eh_recover() again.
|
|
|
|
*/
|
|
|
|
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
2013-11-14 22:32:02 +00:00
|
|
|
reinit_completion(&ap->park_req_pending);
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2008-09-21 09:54:08 +00:00
|
|
|
struct ata_eh_info *ehi = &link->eh_info;
|
|
|
|
|
|
|
|
link->eh_context.i.dev_action[dev->devno] |=
|
|
|
|
ehi->dev_action[dev->devno] & ATA_EH_PARK;
|
|
|
|
ata_eh_clear_action(link, dev, ehi, ATA_EH_PARK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ata_eh_park_issue_cmd(struct ata_device *dev, int park)
|
|
|
|
{
|
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
|
|
|
struct ata_taskfile tf;
|
|
|
|
unsigned int err_mask;
|
|
|
|
|
|
|
|
ata_tf_init(dev, &tf);
|
|
|
|
if (park) {
|
|
|
|
ehc->unloaded_mask |= 1 << dev->devno;
|
|
|
|
tf.command = ATA_CMD_IDLEIMMEDIATE;
|
|
|
|
tf.feature = 0x44;
|
|
|
|
tf.lbal = 0x4c;
|
|
|
|
tf.lbam = 0x4e;
|
|
|
|
tf.lbah = 0x55;
|
|
|
|
} else {
|
|
|
|
ehc->unloaded_mask &= ~(1 << dev->devno);
|
|
|
|
tf.command = ATA_CMD_CHK_POWER;
|
|
|
|
}
|
|
|
|
|
|
|
|
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
|
2016-07-14 00:05:46 +00:00
|
|
|
tf.protocol = ATA_PROT_NODATA;
|
2008-09-21 09:54:08 +00:00
|
|
|
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
|
|
|
if (park && (err_mask || tf.lbal != 0xc4)) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_err(dev, "head unload failed!\n");
|
2008-09-21 09:54:08 +00:00
|
|
|
ehc->unloaded_mask &= ~(1 << dev->devno);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static int ata_eh_revalidate_and_attach(struct ata_link *link,
|
2006-05-31 09:28:03 +00:00
|
|
|
struct ata_device **r_failed_dev)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-15 11:58:22 +00:00
|
|
|
struct ata_device *dev;
|
2007-03-22 13:24:19 +00:00
|
|
|
unsigned int new_mask = 0;
|
2006-05-31 09:28:03 +00:00
|
|
|
unsigned long flags;
|
2007-08-06 09:36:23 +00:00
|
|
|
int rc = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
/* For PATA drive side cable detection to work, IDENTIFY must
|
|
|
|
* be done backwards such that PDIAG- is released by the slave
|
|
|
|
* device before the master device is identified.
|
|
|
|
*/
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL_REVERSE) {
|
2007-08-06 09:36:23 +00:00
|
|
|
unsigned int action = ata_eh_dev_action(dev);
|
|
|
|
unsigned int readid_flags = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2006-11-10 09:08:10 +00:00
|
|
|
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
|
|
|
readid_flags |= ATA_READID_POSTRESET;
|
|
|
|
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
/*
|
|
|
|
* When resuming, before executing any command, make sure to
|
|
|
|
* transition the device to the active power mode.
|
|
|
|
*/
|
|
|
|
if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) {
|
|
|
|
ata_dev_power_set_active(dev);
|
|
|
|
ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
|
|
|
|
}
|
|
|
|
|
2007-05-04 19:27:47 +00:00
|
|
|
if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
|
2007-09-23 04:19:54 +00:00
|
|
|
WARN_ON(dev->class == ATA_DEV_PMP);
|
|
|
|
|
ata: libata-eh: avoid needless hard reset when revalidating link
Performing a revalidation on a AHCI controller supporting LPM,
while using a lpm mode of e.g. med_power_with_dip (hipm + dipm) or
medium_power (hipm), will currently always lead to a hard reset.
The expected behavior is that a hard reset is only performed when
revalidate fails, because the properties of the drive has changed.
A revalidate performed after e.g. a NCQ error, or such a simple thing
as disabling write-caching (hdparm -W 0 /dev/sda), should succeed on
the first try (and should therefore not cause the link to be reset).
This unwarranted hard reset happens because ata_phys_link_offline()
returns true for a link that is in deep sleep. Thus the call to
ata_phys_link_offline() in ata_eh_revalidate_and_attach() will cause
the revalidation to fail, which causes ata_eh_handle_dev_fail() to be
called, which will set ehc->i.action |= ATA_EH_RESET, such that the
link is reset before retrying revalidation.
When the link is reset, the link is reestablished, so when
ata_eh_revalidate_and_attach() is called the second time, directly
after the link has been reset, ata_phys_link_offline() will return
false, and the revalidation will succeed.
Looking at "8.3.1.3 HBA Initiated" in the AHCI 1.3.1 specification,
it is clear the when host software writes a new command to memory,
by setting a bit in the PxCI/PxSACT HBA port registers, the HBA will
automatically bring back the link before sending out the Command FIS.
However, simply reading a SCR (like ata_phys_link_offline() does),
will not cause the HBA to automatically bring back the link.
As long as hipm is enabled, the HBA will put an idle link into deep
sleep. Avoid this needless hard reset on revalidation by temporarily
disabling hipm, by setting the LPM mode to ATA_LPM_MAX_POWER.
After revalidation is complete, ata_eh_recover() will restore the link
policy by setting the LPM mode to ap->target_lpm_policy.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-09-21 15:57:52 +00:00
|
|
|
/*
|
|
|
|
* The link may be in a deep sleep, wake it up.
|
|
|
|
*
|
|
|
|
* If the link is in deep sleep, ata_phys_link_offline()
|
|
|
|
* will return true, causing the revalidation to fail,
|
|
|
|
* which leads to a (potentially) needless hard reset.
|
|
|
|
*
|
|
|
|
* ata_eh_recover() will later restore the link policy
|
|
|
|
* to ap->target_lpm_policy after revalidation is done.
|
|
|
|
*/
|
|
|
|
if (link->lpm_policy > ATA_LPM_MAX_POWER) {
|
|
|
|
rc = ata_eh_set_lpm(link, ATA_LPM_MAX_POWER,
|
|
|
|
r_failed_dev);
|
|
|
|
if (rc)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
|
2006-05-15 11:58:22 +00:00
|
|
|
rc = -EIO;
|
2007-03-22 13:24:19 +00:00
|
|
|
goto err;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_about_to_do(link, dev, ATA_EH_REVALIDATE);
|
2007-09-23 04:14:12 +00:00
|
|
|
rc = ata_dev_revalidate(dev, ehc->classes[dev->devno],
|
|
|
|
readid_flags);
|
2006-05-15 11:58:22 +00:00
|
|
|
if (rc)
|
2007-03-22 13:24:19 +00:00
|
|
|
goto err;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
ata_eh_done(link, dev, ATA_EH_REVALIDATE);
|
2006-06-19 09:27:23 +00:00
|
|
|
|
2006-11-01 09:39:27 +00:00
|
|
|
/* Configuration may have changed, reconfigure
|
|
|
|
* transfer mode.
|
|
|
|
*/
|
|
|
|
ehc->i.flags |= ATA_EHI_SETMODE;
|
|
|
|
|
2006-06-12 04:01:34 +00:00
|
|
|
/* schedule the scsi_rescan_device() here */
|
2023-06-15 08:18:53 +00:00
|
|
|
schedule_delayed_work(&ap->scsi_rescan_task, 0);
|
2006-05-31 09:28:03 +00:00
|
|
|
} else if (dev->class == ATA_DEV_UNKNOWN &&
|
|
|
|
ehc->tries[dev->devno] &&
|
|
|
|
ata_class_enabled(ehc->classes[dev->devno])) {
|
2009-05-09 16:06:54 +00:00
|
|
|
/* Temporarily set dev->class, it will be
|
|
|
|
* permanently set once all configurations are
|
|
|
|
* complete. This is necessary because new
|
|
|
|
* device configuration is done in two
|
|
|
|
* separate loops.
|
|
|
|
*/
|
2006-05-31 09:28:03 +00:00
|
|
|
dev->class = ehc->classes[dev->devno];
|
|
|
|
|
2007-09-23 04:19:54 +00:00
|
|
|
if (dev->class == ATA_DEV_PMP)
|
|
|
|
rc = sata_pmp_attach(dev);
|
|
|
|
else
|
|
|
|
rc = ata_dev_read_id(dev, &dev->class,
|
|
|
|
readid_flags, dev->id);
|
2009-05-09 16:06:54 +00:00
|
|
|
|
|
|
|
/* read_id might have changed class, store and reset */
|
|
|
|
ehc->classes[dev->devno] = dev->class;
|
|
|
|
dev->class = ATA_DEV_UNKNOWN;
|
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
switch (rc) {
|
|
|
|
case 0:
|
2009-01-29 11:31:32 +00:00
|
|
|
/* clear error info accumulated during probe */
|
|
|
|
ata_ering_clear(&dev->ering);
|
2007-08-06 09:36:23 +00:00
|
|
|
new_mask |= 1 << dev->devno;
|
2007-03-22 13:24:19 +00:00
|
|
|
break;
|
|
|
|
case -ENOENT:
|
2006-11-10 09:08:10 +00:00
|
|
|
/* IDENTIFY was issued to non-existent
|
|
|
|
* device. No need to reset. Just
|
2009-05-09 16:06:54 +00:00
|
|
|
* thaw and ignore the device.
|
2006-11-10 09:08:10 +00:00
|
|
|
*/
|
|
|
|
ata_eh_thaw_port(ap);
|
2006-05-31 09:28:03 +00:00
|
|
|
break;
|
2007-03-22 13:24:19 +00:00
|
|
|
default:
|
|
|
|
goto err;
|
2006-05-31 09:28:03 +00:00
|
|
|
}
|
2007-03-22 13:24:19 +00:00
|
|
|
}
|
|
|
|
}
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2007-04-22 17:05:53 +00:00
|
|
|
/* PDIAG- should have been released, ask cable type if post-reset */
|
2008-02-13 00:15:09 +00:00
|
|
|
if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) {
|
|
|
|
if (ap->ops->cable_detect)
|
|
|
|
ap->cbl = ap->ops->cable_detect(ap);
|
|
|
|
ata_force_cbl(ap);
|
|
|
|
}
|
2007-04-22 17:05:53 +00:00
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
/* Configure new devices forward such that user doesn't see
|
|
|
|
* device detection messages backwards.
|
|
|
|
*/
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2009-10-15 14:37:32 +00:00
|
|
|
if (!(new_mask & (1 << dev->devno)))
|
2007-03-22 13:24:19 +00:00
|
|
|
continue;
|
|
|
|
|
2009-05-09 16:06:54 +00:00
|
|
|
dev->class = ehc->classes[dev->devno];
|
|
|
|
|
2009-10-15 14:37:32 +00:00
|
|
|
if (dev->class == ATA_DEV_PMP)
|
|
|
|
continue;
|
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
ehc->i.flags |= ATA_EHI_PRINTINFO;
|
|
|
|
rc = ata_dev_configure(dev);
|
|
|
|
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
|
2009-05-09 16:06:54 +00:00
|
|
|
if (rc) {
|
|
|
|
dev->class = ATA_DEV_UNKNOWN;
|
2007-03-22 13:24:19 +00:00
|
|
|
goto err;
|
2009-05-09 16:06:54 +00:00
|
|
|
}
|
2007-03-22 13:24:19 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
|
|
|
/* new device discovered, configure xfermode */
|
|
|
|
ehc->i.flags |= ATA_EHI_SETMODE;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
return 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-03-22 13:24:19 +00:00
|
|
|
err:
|
|
|
|
*r_failed_dev = dev;
|
2006-05-15 11:58:22 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:55 +00:00
|
|
|
/**
|
|
|
|
* ata_set_mode - Program timings and issue SET FEATURES - XFER
|
|
|
|
* @link: link on which timings will be programmed
|
2009-04-22 16:21:29 +00:00
|
|
|
* @r_failed_dev: out parameter for failed device
|
2007-11-27 10:28:55 +00:00
|
|
|
*
|
|
|
|
* Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If
|
|
|
|
* ata_set_mode() fails, pointer to the failing device is
|
|
|
|
* returned in @r_failed_dev.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* PCI/etc. bus probe sem.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, negative errno otherwise
|
|
|
|
*/
|
|
|
|
int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|
|
|
{
|
|
|
|
struct ata_port *ap = link->ap;
|
2007-11-27 10:28:58 +00:00
|
|
|
struct ata_device *dev;
|
|
|
|
int rc;
|
2007-11-27 10:28:55 +00:00
|
|
|
|
2007-11-27 10:28:59 +00:00
|
|
|
/* if data transfer is verified, clear DUBIOUS_XFER on ering top */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ENABLED) {
|
2007-11-27 10:28:59 +00:00
|
|
|
if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
|
|
|
|
struct ata_ering_entry *ent;
|
|
|
|
|
|
|
|
ent = ata_ering_top(&dev->ering);
|
|
|
|
if (ent)
|
|
|
|
ent->eflags &= ~ATA_EFLAG_DUBIOUS_XFER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:55 +00:00
|
|
|
/* has private set_mode? */
|
|
|
|
if (ap->ops->set_mode)
|
2007-11-27 10:28:58 +00:00
|
|
|
rc = ap->ops->set_mode(link, r_failed_dev);
|
|
|
|
else
|
|
|
|
rc = ata_do_set_mode(link, r_failed_dev);
|
|
|
|
|
|
|
|
/* if transfer mode has changed, set DUBIOUS_XFER on device */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ENABLED) {
|
2007-11-27 10:28:58 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
|
|
|
u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno];
|
|
|
|
u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));
|
|
|
|
|
|
|
|
if (dev->xfer_mode != saved_xfer_mode ||
|
|
|
|
ata_ncq_enabled(dev) != saved_ncq)
|
|
|
|
dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
2007-11-27 10:28:55 +00:00
|
|
|
}
|
|
|
|
|
2008-08-30 12:20:01 +00:00
|
|
|
/**
|
|
|
|
* atapi_eh_clear_ua - Clear ATAPI UNIT ATTENTION after reset
|
|
|
|
* @dev: ATAPI device to clear UA for
|
|
|
|
*
|
|
|
|
* Resets and other operations can make an ATAPI device raise
|
|
|
|
* UNIT ATTENTION which causes the next operation to fail. This
|
|
|
|
* function clears UA.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, -errno on failure.
|
|
|
|
*/
|
|
|
|
static int atapi_eh_clear_ua(struct ata_device *dev)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ATA_EH_UA_TRIES; i++) {
|
2009-03-02 09:55:16 +00:00
|
|
|
u8 *sense_buffer = dev->link->ap->sector_buf;
|
2008-08-30 12:20:01 +00:00
|
|
|
u8 sense_key = 0;
|
|
|
|
unsigned int err_mask;
|
|
|
|
|
|
|
|
err_mask = atapi_eh_tur(dev, &sense_key);
|
|
|
|
if (err_mask != 0 && err_mask != AC_ERR_DEV) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev,
|
|
|
|
"TEST_UNIT_READY failed (err_mask=0x%x)\n",
|
|
|
|
err_mask);
|
2008-08-30 12:20:01 +00:00
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!err_mask || sense_key != UNIT_ATTENTION)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_mask = atapi_eh_request_sense(dev, sense_buffer, sense_key);
|
|
|
|
if (err_mask) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev, "failed to clear "
|
2008-08-30 12:20:01 +00:00
|
|
|
"UNIT ATTENTION (err_mask=0x%x)\n", err_mask);
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev, "UNIT ATTENTION persists after %d tries\n",
|
|
|
|
ATA_EH_UA_TRIES);
|
2008-08-30 12:20:01 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-19 06:36:45 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_maybe_retry_flush - Retry FLUSH if necessary
|
|
|
|
* @dev: ATA device which may need FLUSH retry
|
|
|
|
*
|
|
|
|
* If @dev failed FLUSH, it needs to be reported upper layer
|
|
|
|
* immediately as it means that @dev failed to remap and already
|
|
|
|
* lost at least a sector and further FLUSH retrials won't make
|
|
|
|
* any difference to the lost sector. However, if FLUSH failed
|
|
|
|
* for other reasons, for example transmission error, FLUSH needs
|
|
|
|
* to be retried.
|
|
|
|
*
|
|
|
|
* This function determines whether FLUSH failure retry is
|
|
|
|
* necessary and performs it if so.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 if EH can continue, -errno if EH needs to be repeated.
|
|
|
|
*/
|
|
|
|
static int ata_eh_maybe_retry_flush(struct ata_device *dev)
|
|
|
|
{
|
|
|
|
struct ata_link *link = dev->link;
|
|
|
|
struct ata_port *ap = link->ap;
|
|
|
|
struct ata_queued_cmd *qc;
|
|
|
|
struct ata_taskfile tf;
|
|
|
|
unsigned int err_mask;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
/* did flush fail for this device? */
|
|
|
|
if (!ata_tag_valid(link->active_tag))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
qc = __ata_qc_from_tag(ap, link->active_tag);
|
|
|
|
if (qc->dev != dev || (qc->tf.command != ATA_CMD_FLUSH_EXT &&
|
|
|
|
qc->tf.command != ATA_CMD_FLUSH))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* if the device failed it, it should be reported to upper layers */
|
|
|
|
if (qc->err_mask & AC_ERR_DEV)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* flush failed for some other reason, give it another shot */
|
|
|
|
ata_tf_init(dev, &tf);
|
|
|
|
|
|
|
|
tf.command = qc->tf.command;
|
|
|
|
tf.flags |= ATA_TFLAG_DEVICE;
|
|
|
|
tf.protocol = ATA_PROT_NODATA;
|
|
|
|
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev, "retrying FLUSH 0x%x Emask 0x%x\n",
|
2009-11-19 06:36:45 +00:00
|
|
|
tf.command, qc->err_mask);
|
|
|
|
|
|
|
|
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
|
|
|
if (!err_mask) {
|
|
|
|
/*
|
|
|
|
* FLUSH is complete but there's no way to
|
|
|
|
* successfully complete a failed command from EH.
|
|
|
|
* Making sure retry is allowed at least once and
|
|
|
|
* retrying it should do the trick - whatever was in
|
|
|
|
* the cache is already on the platter and this won't
|
|
|
|
* cause infinite loop.
|
|
|
|
*/
|
|
|
|
qc->scsicmd->allowed = max(qc->scsicmd->allowed, 1);
|
|
|
|
} else {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev, "FLUSH failed Emask 0x%x\n",
|
2009-11-19 06:36:45 +00:00
|
|
|
err_mask);
|
|
|
|
rc = -EIO;
|
|
|
|
|
|
|
|
/* if device failed it, report it to upper layers */
|
|
|
|
if (err_mask & AC_ERR_DEV) {
|
|
|
|
qc->err_mask |= AC_ERR_DEV;
|
|
|
|
qc->result_tf = tf;
|
2022-10-07 13:23:38 +00:00
|
|
|
if (!ata_port_is_frozen(ap))
|
2009-11-19 06:36:45 +00:00
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_set_lpm - configure SATA interface power management
|
|
|
|
* @link: link to configure power management
|
|
|
|
* @policy: the link power management policy
|
|
|
|
* @r_failed_dev: out parameter for failed device
|
|
|
|
*
|
|
|
|
* Enable SATA Interface power management. This will enable
|
2017-09-14 10:35:36 +00:00
|
|
|
* Device Interface Power Management (DIPM) for min_power and
|
|
|
|
* medium_power_with_dipm policies, and then call driver specific
|
|
|
|
* callbacks for enabling Host Initiated Power management.
|
2010-09-01 15:50:06 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* EH context.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, -errno on failure.
|
|
|
|
*/
|
|
|
|
static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|
|
|
struct ata_device **r_failed_dev)
|
|
|
|
{
|
2010-09-01 15:50:07 +00:00
|
|
|
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
|
2010-09-01 15:50:06 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
|
|
|
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
|
2010-12-09 15:13:15 +00:00
|
|
|
enum ata_lpm_policy old_policy = link->lpm_policy;
|
2011-05-09 14:04:11 +00:00
|
|
|
bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM;
|
2010-09-01 15:50:06 +00:00
|
|
|
unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
|
|
|
|
unsigned int err_mask;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
/* if the link or host doesn't do LPM, noop */
|
2020-03-26 15:58:10 +00:00
|
|
|
if (!IS_ENABLED(CONFIG_SATA_HOST) ||
|
|
|
|
(link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))
|
2010-09-01 15:50:06 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DIPM is enabled only for MIN_POWER as some devices
|
|
|
|
* misbehave when the host NACKs transition to SLUMBER. Order
|
|
|
|
* device and link configurations such that the host always
|
|
|
|
* allows DIPM requests.
|
|
|
|
*/
|
|
|
|
ata_for_each_dev(dev, link, ENABLED) {
|
|
|
|
bool hipm = ata_id_has_hipm(dev->id);
|
2011-03-16 10:14:55 +00:00
|
|
|
bool dipm = ata_id_has_dipm(dev->id) && !no_dipm;
|
2010-09-01 15:50:06 +00:00
|
|
|
|
|
|
|
/* find the first enabled and LPM enabled devices */
|
|
|
|
if (!link_dev)
|
|
|
|
link_dev = dev;
|
|
|
|
|
|
|
|
if (!lpm_dev && (hipm || dipm))
|
|
|
|
lpm_dev = dev;
|
|
|
|
|
|
|
|
hints &= ~ATA_LPM_EMPTY;
|
|
|
|
if (!hipm)
|
|
|
|
hints &= ~ATA_LPM_HIPM;
|
|
|
|
|
|
|
|
/* disable DIPM before changing link config */
|
2017-09-14 10:35:36 +00:00
|
|
|
if (policy < ATA_LPM_MED_POWER_WITH_DIPM && dipm) {
|
2010-09-01 15:50:06 +00:00
|
|
|
err_mask = ata_dev_set_feature(dev,
|
|
|
|
SETFEATURES_SATA_DISABLE, SATA_DIPM);
|
|
|
|
if (err_mask && err_mask != AC_ERR_DEV) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev,
|
|
|
|
"failed to disable DIPM, Emask 0x%x\n",
|
|
|
|
err_mask);
|
2010-09-01 15:50:06 +00:00
|
|
|
rc = -EIO;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-01 15:50:07 +00:00
|
|
|
if (ap) {
|
|
|
|
rc = ap->ops->set_lpm(link, policy, hints);
|
|
|
|
if (!rc && ap->slave_link)
|
|
|
|
rc = ap->ops->set_lpm(ap->slave_link, policy, hints);
|
|
|
|
} else
|
|
|
|
rc = sata_pmp_set_lpm(link, policy, hints);
|
2010-09-01 15:50:06 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Attribute link config failure to the first (LPM) enabled
|
|
|
|
* device on the link.
|
|
|
|
*/
|
|
|
|
if (rc) {
|
|
|
|
if (rc == -EOPNOTSUPP) {
|
|
|
|
link->flags |= ATA_LFLAG_NO_LPM;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
dev = lpm_dev ? lpm_dev : link_dev;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2010-12-09 15:13:15 +00:00
|
|
|
/*
|
|
|
|
* Low level driver acked the transition. Issue DIPM command
|
|
|
|
* with the new policy set.
|
|
|
|
*/
|
|
|
|
link->lpm_policy = policy;
|
|
|
|
if (ap && ap->slave_link)
|
|
|
|
ap->slave_link->lpm_policy = policy;
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
/* host config updated, enable DIPM if transitioning to MIN_POWER */
|
|
|
|
ata_for_each_dev(dev, link, ENABLED) {
|
2017-09-14 10:35:36 +00:00
|
|
|
if (policy >= ATA_LPM_MED_POWER_WITH_DIPM && !no_dipm &&
|
2011-03-16 10:14:55 +00:00
|
|
|
ata_id_has_dipm(dev->id)) {
|
2010-09-01 15:50:06 +00:00
|
|
|
err_mask = ata_dev_set_feature(dev,
|
|
|
|
SETFEATURES_SATA_ENABLE, SATA_DIPM);
|
|
|
|
if (err_mask && err_mask != AC_ERR_DEV) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_dev_warn(dev,
|
2010-09-01 15:50:06 +00:00
|
|
|
"failed to enable DIPM, Emask 0x%x\n",
|
|
|
|
err_mask);
|
|
|
|
rc = -EIO;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-25 17:52:37 +00:00
|
|
|
link->last_lpm_change = jiffies;
|
|
|
|
link->flags |= ATA_LFLAG_CHANGED;
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
2010-12-09 15:13:15 +00:00
|
|
|
/* restore the old policy */
|
|
|
|
link->lpm_policy = old_policy;
|
|
|
|
if (ap && ap->slave_link)
|
|
|
|
ap->slave_link->lpm_policy = old_policy;
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
/* if no device or only one more chance is left, disable LPM */
|
|
|
|
if (!dev || ehc->tries[dev->devno] <= 2) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_warn(link, "disabling LPM on the link\n");
|
2010-09-01 15:50:06 +00:00
|
|
|
link->flags |= ATA_LFLAG_NO_LPM;
|
|
|
|
}
|
|
|
|
if (r_failed_dev)
|
|
|
|
*r_failed_dev = dev;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2011-03-04 18:24:11 +00:00
|
|
|
int ata_link_nr_enabled(struct ata_link *link)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *dev;
|
|
|
|
int cnt = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ENABLED)
|
|
|
|
cnt++;
|
2006-05-15 11:58:22 +00:00
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static int ata_link_nr_vacant(struct ata_link *link)
|
2006-05-31 09:28:03 +00:00
|
|
|
{
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *dev;
|
|
|
|
int cnt = 0;
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL)
|
2007-08-06 09:36:23 +00:00
|
|
|
if (dev->class == ATA_DEV_UNKNOWN)
|
2006-05-31 09:28:03 +00:00
|
|
|
cnt++;
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:23 +00:00
|
|
|
static int ata_eh_skip_recovery(struct ata_link *link)
|
2006-05-31 09:28:03 +00:00
|
|
|
{
|
2008-01-23 15:05:14 +00:00
|
|
|
struct ata_port *ap = link->ap;
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2007-08-06 09:36:23 +00:00
|
|
|
struct ata_device *dev;
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2007-09-23 04:14:13 +00:00
|
|
|
/* skip disabled links */
|
|
|
|
if (link->flags & ATA_LFLAG_DISABLED)
|
|
|
|
return 1;
|
|
|
|
|
2010-09-07 12:05:31 +00:00
|
|
|
/* skip if explicitly requested */
|
|
|
|
if (ehc->i.flags & ATA_EHI_NO_RECOVERY)
|
|
|
|
return 1;
|
|
|
|
|
2008-01-23 15:05:14 +00:00
|
|
|
/* thaw frozen port and recover failed devices */
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(ap) || ata_link_nr_enabled(link))
|
2008-01-23 15:05:14 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* reset at least once if reset is requested */
|
|
|
|
if ((ehc->i.action & ATA_EH_RESET) &&
|
|
|
|
!(ehc->i.flags & ATA_EHI_DID_RESET))
|
2006-05-31 09:28:03 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* skip if class codes for all vacant slots are ATA_DEV_NONE */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2006-05-31 09:28:03 +00:00
|
|
|
if (dev->class == ATA_DEV_UNKNOWN &&
|
|
|
|
ehc->classes[dev->devno] != ATA_DEV_NONE)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-01-29 11:31:34 +00:00
|
|
|
static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg)
|
|
|
|
{
|
|
|
|
u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL);
|
|
|
|
u64 now = get_jiffies_64();
|
|
|
|
int *trials = void_arg;
|
|
|
|
|
2012-05-03 14:15:07 +00:00
|
|
|
if ((ent->eflags & ATA_EFLAG_OLD_ER) ||
|
|
|
|
(ent->timestamp < now - min(now, interval)))
|
2009-01-29 11:31:34 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
(*trials)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-27 10:28:54 +00:00
|
|
|
static int ata_eh_schedule_probe(struct ata_device *dev)
|
|
|
|
{
|
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
2009-01-29 11:31:34 +00:00
|
|
|
struct ata_link *link = ata_dev_phys_link(dev);
|
|
|
|
int trials = 0;
|
2007-11-27 10:28:54 +00:00
|
|
|
|
|
|
|
if (!(ehc->i.probe_mask & (1 << dev->devno)) ||
|
|
|
|
(ehc->did_probe_mask & (1 << dev->devno)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ata_eh_detach_dev(dev);
|
|
|
|
ata_dev_init(dev);
|
|
|
|
ehc->did_probe_mask |= (1 << dev->devno);
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action |= ATA_EH_RESET;
|
2007-11-27 10:28:58 +00:00
|
|
|
ehc->saved_xfer_mode[dev->devno] = 0;
|
|
|
|
ehc->saved_ncq_enabled &= ~(1 << dev->devno);
|
2007-11-27 10:28:54 +00:00
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
/* the link maybe in a deep sleep, wake it up */
|
2010-09-01 15:50:07 +00:00
|
|
|
if (link->lpm_policy > ATA_LPM_MAX_POWER) {
|
|
|
|
if (ata_is_host_link(link))
|
|
|
|
link->ap->ops->set_lpm(link, ATA_LPM_MAX_POWER,
|
|
|
|
ATA_LPM_EMPTY);
|
|
|
|
else
|
|
|
|
sata_pmp_set_lpm(link, ATA_LPM_MAX_POWER,
|
|
|
|
ATA_LPM_EMPTY);
|
|
|
|
}
|
2010-09-01 15:50:06 +00:00
|
|
|
|
2009-01-29 11:31:34 +00:00
|
|
|
/* Record and count probe trials on the ering. The specific
|
|
|
|
* error mask used is irrelevant. Because a successful device
|
|
|
|
* detection clears the ering, this count accumulates only if
|
|
|
|
* there are consecutive failed probes.
|
|
|
|
*
|
|
|
|
* If the count is equal to or higher than ATA_EH_PROBE_TRIALS
|
|
|
|
* in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is
|
|
|
|
* forced to 1.5Gbps.
|
|
|
|
*
|
|
|
|
* This is to work around cases where failed link speed
|
|
|
|
* negotiation results in device misdetection leading to
|
|
|
|
* infinite DEVXCHG or PHRDY CHG events.
|
|
|
|
*/
|
|
|
|
ata_ering_record(&dev->ering, 0, AC_ERR_OTHER);
|
|
|
|
ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials);
|
|
|
|
|
|
|
|
if (trials > ATA_EH_PROBE_TRIALS)
|
|
|
|
sata_down_spd_limit(link, 1);
|
|
|
|
|
2007-11-27 10:28:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
|
2007-07-01 10:05:58 +00:00
|
|
|
{
|
2007-08-06 09:36:22 +00:00
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
2007-07-01 10:05:58 +00:00
|
|
|
|
2009-01-29 11:31:35 +00:00
|
|
|
/* -EAGAIN from EH routine indicates retry without prejudice.
|
|
|
|
* The requester is responsible for ensuring forward progress.
|
|
|
|
*/
|
|
|
|
if (err != -EAGAIN)
|
|
|
|
ehc->tries[dev->devno]--;
|
2007-07-01 10:05:58 +00:00
|
|
|
|
|
|
|
switch (err) {
|
|
|
|
case -ENODEV:
|
|
|
|
/* device missing or wrong IDENTIFY data, schedule probing */
|
|
|
|
ehc->i.probe_mask |= (1 << dev->devno);
|
2020-08-23 22:36:59 +00:00
|
|
|
fallthrough;
|
2007-07-01 10:05:58 +00:00
|
|
|
case -EINVAL:
|
|
|
|
/* give it just one more chance */
|
|
|
|
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
|
2020-08-23 22:36:59 +00:00
|
|
|
fallthrough;
|
2007-07-01 10:05:58 +00:00
|
|
|
case -EIO:
|
2009-01-29 11:31:29 +00:00
|
|
|
if (ehc->tries[dev->devno] == 1) {
|
2007-07-01 10:05:58 +00:00
|
|
|
/* This is the last chance, better to slow
|
|
|
|
* down than lose it.
|
|
|
|
*/
|
2009-01-29 11:31:33 +00:00
|
|
|
sata_down_spd_limit(ata_dev_phys_link(dev), 0);
|
2009-01-29 11:31:29 +00:00
|
|
|
if (dev->pio_mode > XFER_PIO_0)
|
|
|
|
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
|
2007-07-01 10:05:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
|
|
|
|
/* disable device if it has used up all its chances */
|
|
|
|
ata_dev_disable(dev);
|
|
|
|
|
|
|
|
/* detach if offline */
|
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init().
In libata, a port contains links and a link contains devices. There
is single host link but if a PMP is attached to it, there can be
multiple fan-out links. On SATA, there's usually a single device
connected to a link but PATA and SATA controllers emulating TF based
interface can have two - master and slave.
However, there are a few controllers which don't fit into this
abstraction too well - SATA controllers which emulate TF interface
with both master and slave devices but also have separate SCR
register sets for each device. These controllers need separate links
for physical link handling (e.g. onlineness, link speed) but should
be treated like a traditional M/S controller for everything else
(e.g. command issue, softreset).
slave_link is libata's way of handling this class of controllers
without impacting core layer too much. For anything other than
physical link handling, the default host link is used for both master
and slave. For physical link handling, separate @ap->slave_link is
used. All dirty details are implemented inside libata core layer.
From LLD's POV, the only difference is that prereset, hardreset and
postreset are called once more for the slave link, so the reset
sequence looks like the following.
prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
softreset(M) -> postreset(M) -> postreset(S)
Note that softreset is called only for the master. Softreset resets
both M/S by definition, so SRST on master should handle both (the
standard method will work just fine).
As slave_link excludes PMP support and only code paths which deal with
the attributes of physical link are affected, all the changes are
localized to libata.h, libata-core.c and libata-eh.c.
* ata_is_host_link() updated so that slave_link is considered as host
link too.
* iterator extended to iterate over the slave_link when using the
underbarred version.
* force param handling updated such that devno 16 is mapped to the
slave link/device.
* ata_link_on/offline() updated to return the combined result from
master and slave link. ata_phys_link_on/offline() are the direct
versions.
* EH autopsy and report are performed separately for master slave
links. Reset is udpated to implement the above described reset
sequence.
Except for reset update, most changes are minor, many of them just
modifying dev->link to ata_dev_phys_link(dev) or using phys online
test instead.
After this update, LLDs can take full advantage of per-dev SCR
registers by simply turning on slave link.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2008-07-31 08:02:43 +00:00
|
|
|
if (ata_phys_link_offline(ata_dev_phys_link(dev)))
|
2007-07-01 10:05:58 +00:00
|
|
|
ata_eh_detach_dev(dev);
|
|
|
|
|
2007-11-27 10:28:54 +00:00
|
|
|
/* schedule probe if necessary */
|
2008-05-19 17:17:54 +00:00
|
|
|
if (ata_eh_schedule_probe(dev)) {
|
2007-07-01 10:05:58 +00:00
|
|
|
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
2008-05-19 17:17:54 +00:00
|
|
|
memset(ehc->cmd_timeout_idx[dev->devno], 0,
|
|
|
|
sizeof(ehc->cmd_timeout_idx[dev->devno]));
|
|
|
|
}
|
2007-08-06 09:36:24 +00:00
|
|
|
|
|
|
|
return 1;
|
2007-07-01 10:05:58 +00:00
|
|
|
} else {
|
libata: prefer hardreset
When both soft and hard resets are available, libata preferred
softreset till now. The logic behind it was to be softer to devices;
however, this doesn't really help much. Rationales for the change:
* BIOS may freeze lock certain things during boot and softreset can't
unlock those. This by itself is okay but during operation PHY event
or other error conditions can trigger hardreset and the device may
end up with different configuration.
For example, after a hardreset, previously unlockable HPA can be
unlocked resulting in different device size and thus revalidation
failure. Similar condition can occur during or after resume.
* Certain ATAPI devices require hardreset to recover after certain
error conditions. On PATA, this is done by issuing the DEVICE RESET
command. On SATA, COMRESET has equivalent effect. The problem is
that DEVICE RESET needs its own execution protocol.
For SFF controllers with bare TF access, it can be easily
implemented but more advanced controllers (e.g. ahci and sata_sil24)
require specialized implementations. Simply using hardreset solves
the problem nicely.
* COMRESET initialization sequence is the norm in SATA land and many
SATA devices don't work properly if only SRST is used. For example,
some PMPs behave this way and libata works around by always issuing
hardreset if the host supports PMP.
Like the above example, libata has developed a number of mechanisms
aiming to promote softreset to hardreset if softreset is not going
to work. This approach is time consuming and error prone.
Also, note that, dependingon how you read the specs, it could be
argued that PMP fan-out ports require COMRESET to start operation.
In fact, all the PMPs on the market except one don't work properly
if COMRESET is not issued to fan-out ports after PMP reset.
* COMRESET is an integral part of SATA connection and any working
device should be able to handle COMRESET properly. After all, it's
the way to signal hardreset during reboot. This is the most used
and recommended (at least by the ahci spec) method of resetting
devices.
So, this patch makes libata prefer hardreset over softreset by making
the following changes.
* Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
now only used to tell prereset whether soft or hard reset will be
issued.
* Strip out now unneeded promote-to-hardreset logics from
ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
other places.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-01-23 15:05:14 +00:00
|
|
|
ehc->i.action |= ATA_EH_RESET;
|
2007-08-06 09:36:24 +00:00
|
|
|
return 0;
|
2007-07-01 10:05:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_recover - recover host port after error
|
|
|
|
* @ap: host port to recover
|
2006-05-31 09:27:48 +00:00
|
|
|
* @prereset: prereset method (can be NULL)
|
2006-05-15 11:58:22 +00:00
|
|
|
* @softreset: softreset method (can be NULL)
|
|
|
|
* @hardreset: hardreset method (can be NULL)
|
|
|
|
* @postreset: postreset method (can be NULL)
|
2007-08-06 09:36:24 +00:00
|
|
|
* @r_failed_link: out parameter for failed link
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* This is the alpha and omega, eum and yang, heart and soul of
|
|
|
|
* libata exception handling. On entry, actions required to
|
2007-08-06 09:36:24 +00:00
|
|
|
* recover each link and hotplug requests are recorded in the
|
|
|
|
* link's eh_context. This function executes all the operations
|
|
|
|
* with appropriate retrials and fallbacks to resurrect failed
|
2006-05-31 09:28:03 +00:00
|
|
|
* devices, detach goners and greet newcomers.
|
2006-05-15 11:58:22 +00:00
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* 0 on success, -errno on failure.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|
|
|
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
|
|
|
|
ata_postreset_fn_t postreset,
|
|
|
|
struct ata_link **r_failed_link)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:24 +00:00
|
|
|
struct ata_link *link;
|
2006-05-15 11:58:22 +00:00
|
|
|
struct ata_device *dev;
|
2010-09-01 15:50:06 +00:00
|
|
|
int rc, nr_fails;
|
2008-09-21 09:54:08 +00:00
|
|
|
unsigned long flags, deadline;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
|
|
|
/* prep for recovery */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
2007-08-06 09:36:24 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2007-09-23 04:14:13 +00:00
|
|
|
/* re-enable link? */
|
|
|
|
if (ehc->i.action & ATA_EH_ENABLE_LINK) {
|
|
|
|
ata_eh_about_to_do(link, NULL, ATA_EH_ENABLE_LINK);
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
link->flags &= ~ATA_LFLAG_DISABLED;
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK);
|
|
|
|
}
|
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2007-09-23 04:14:12 +00:00
|
|
|
if (link->flags & ATA_LFLAG_NO_RETRY)
|
|
|
|
ehc->tries[dev->devno] = 1;
|
|
|
|
else
|
|
|
|
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* collect port action mask recorded in dev actions */
|
|
|
|
ehc->i.action |= ehc->i.dev_action[dev->devno] &
|
|
|
|
~ATA_EH_PERDEV_MASK;
|
|
|
|
ehc->i.dev_action[dev->devno] &= ATA_EH_PERDEV_MASK;
|
|
|
|
|
|
|
|
/* process hotplug request */
|
|
|
|
if (dev->flags & ATA_DFLAG_DETACH)
|
|
|
|
ata_eh_detach_dev(dev);
|
|
|
|
|
2007-11-27 10:28:54 +00:00
|
|
|
/* schedule probe if necessary */
|
|
|
|
if (!ata_dev_enabled(dev))
|
|
|
|
ata_eh_schedule_probe(dev);
|
2006-05-31 09:28:03 +00:00
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
retry:
|
|
|
|
rc = 0;
|
|
|
|
|
2006-06-12 05:11:43 +00:00
|
|
|
/* if UNLOADING, finish immediately */
|
2006-06-28 16:29:30 +00:00
|
|
|
if (ap->pflags & ATA_PFLAG_UNLOADING)
|
2006-06-12 05:11:43 +00:00
|
|
|
goto out;
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* prep for EH */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
2007-08-06 09:36:24 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* skip EH if possible. */
|
|
|
|
if (ata_eh_skip_recovery(link))
|
|
|
|
ehc->i.action = 0;
|
|
|
|
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL)
|
2007-08-06 09:36:24 +00:00
|
|
|
ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
|
|
|
|
}
|
2006-05-31 09:28:03 +00:00
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
/* reset */
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
2008-05-18 16:15:07 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2007-08-06 09:36:24 +00:00
|
|
|
|
2008-05-18 16:15:07 +00:00
|
|
|
if (!(ehc->i.action & ATA_EH_RESET))
|
|
|
|
continue;
|
2007-08-06 09:36:24 +00:00
|
|
|
|
2008-05-18 16:15:07 +00:00
|
|
|
rc = ata_eh_reset(link, ata_link_nr_vacant(link),
|
|
|
|
prereset, softreset, hardreset, postreset);
|
|
|
|
if (rc) {
|
ata: Convert ata_<foo>_printk(KERN_<LEVEL> to ata_<foo>_<level>
Saves text by removing nearly duplicated text format strings by
creating ata_<foo>_printk functions and printf extension %pV.
ata defconfig size shrinks ~5% (~8KB), allyesconfig ~2.5% (~13KB)
Format string duplication comes from:
#define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0)
Coalesce long formats.
$ size drivers/ata/built-in.*
text data bss dec hex filename
544969 73893 116584 735446 b38d6 drivers/ata/built-in.allyesconfig.ata.o
558429 73893 117864 750186 b726a drivers/ata/built-in.allyesconfig.dev_level.o
141328 14689 4220 160237 271ed drivers/ata/built-in.defconfig.ata.o
149567 14689 4220 168476 2921c drivers/ata/built-in.defconfig.dev_level.o
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
2011-04-15 22:51:59 +00:00
|
|
|
ata_link_err(link, "reset failed, giving up\n");
|
2008-05-18 16:15:07 +00:00
|
|
|
goto out;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-21 09:54:08 +00:00
|
|
|
do {
|
|
|
|
unsigned long now;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* clears ATA_EH_PARK in eh_info and resets
|
|
|
|
* ap->park_req_pending
|
|
|
|
*/
|
|
|
|
ata_eh_pull_park_action(ap);
|
|
|
|
|
|
|
|
deadline = jiffies;
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2008-09-21 09:54:08 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
|
|
|
unsigned long tmp;
|
|
|
|
|
2014-11-05 12:08:21 +00:00
|
|
|
if (dev->class != ATA_DEV_ATA &&
|
|
|
|
dev->class != ATA_DEV_ZAC)
|
2008-09-21 09:54:08 +00:00
|
|
|
continue;
|
|
|
|
if (!(ehc->i.dev_action[dev->devno] &
|
|
|
|
ATA_EH_PARK))
|
|
|
|
continue;
|
|
|
|
tmp = dev->unpark_deadline;
|
|
|
|
if (time_before(deadline, tmp))
|
|
|
|
deadline = tmp;
|
|
|
|
else if (time_before_eq(tmp, jiffies))
|
|
|
|
continue;
|
|
|
|
if (ehc->unloaded_mask & (1 << dev->devno))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ata_eh_park_issue_cmd(dev, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
now = jiffies;
|
|
|
|
if (time_before_eq(deadline, now))
|
|
|
|
break;
|
|
|
|
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
ata_eh_release(ap);
|
2008-09-21 09:54:08 +00:00
|
|
|
deadline = wait_for_completion_timeout(&ap->park_req_pending,
|
|
|
|
deadline - now);
|
libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected. However, libata EH didn't
guarantee exclusion among EHs for ports of the same host. IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.
In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).
This patch implements exclusion among EHs of the same host. When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release(). EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.
This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH. This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.
This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla. :-)
https://bugzilla.kernel.org/show_bug.cgi?id=8223
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-09-06 15:57:14 +00:00
|
|
|
ata_eh_acquire(ap);
|
2008-09-21 09:54:08 +00:00
|
|
|
} while (deadline);
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_link(link, ap, EDGE) {
|
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2008-09-21 09:54:08 +00:00
|
|
|
if (!(link->eh_context.unloaded_mask &
|
|
|
|
(1 << dev->devno)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ata_eh_park_issue_cmd(dev, 0);
|
|
|
|
ata_eh_done(link, dev, ATA_EH_PARK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* the rest */
|
2010-09-01 15:50:06 +00:00
|
|
|
nr_fails = 0;
|
|
|
|
ata_for_each_link(link, ap, PMP_FIRST) {
|
2007-08-06 09:36:24 +00:00
|
|
|
struct ata_eh_context *ehc = &link->eh_context;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
if (sata_pmp_attached(ap) && ata_is_host_link(link))
|
|
|
|
goto config_lpm;
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* revalidate existing devices and attach new ones */
|
|
|
|
rc = ata_eh_revalidate_and_attach(link, &dev);
|
2007-02-02 07:22:30 +00:00
|
|
|
if (rc)
|
2010-09-01 15:50:06 +00:00
|
|
|
goto rest_fail;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-09-23 04:19:54 +00:00
|
|
|
/* if PMP got attached, return, pmp EH will take care of it */
|
|
|
|
if (link->device->class == ATA_DEV_PMP) {
|
|
|
|
ehc->i.action = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* configure transfer mode if necessary */
|
|
|
|
if (ehc->i.flags & ATA_EHI_SETMODE) {
|
|
|
|
rc = ata_set_mode(link, &dev);
|
|
|
|
if (rc)
|
2010-09-01 15:50:06 +00:00
|
|
|
goto rest_fail;
|
2007-08-06 09:36:24 +00:00
|
|
|
ehc->i.flags &= ~ATA_EHI_SETMODE;
|
|
|
|
}
|
|
|
|
|
2008-08-30 12:20:01 +00:00
|
|
|
/* If reset has been issued, clear UA to avoid
|
|
|
|
* disrupting the current users of the device.
|
|
|
|
*/
|
|
|
|
if (ehc->i.flags & ATA_EHI_DID_RESET) {
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2008-08-30 12:20:01 +00:00
|
|
|
if (dev->class != ATA_DEV_ATAPI)
|
|
|
|
continue;
|
|
|
|
rc = atapi_eh_clear_ua(dev);
|
|
|
|
if (rc)
|
2010-09-01 15:50:06 +00:00
|
|
|
goto rest_fail;
|
2013-01-15 09:21:01 +00:00
|
|
|
if (zpodd_dev_enabled(dev))
|
|
|
|
zpodd_post_poweron(dev);
|
2008-08-30 12:20:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-19 06:36:45 +00:00
|
|
|
/* retry flush if necessary */
|
|
|
|
ata_for_each_dev(dev, link, ALL) {
|
2014-11-05 12:08:21 +00:00
|
|
|
if (dev->class != ATA_DEV_ATA &&
|
|
|
|
dev->class != ATA_DEV_ZAC)
|
2009-11-19 06:36:45 +00:00
|
|
|
continue;
|
|
|
|
rc = ata_eh_maybe_retry_flush(dev);
|
|
|
|
if (rc)
|
2010-09-01 15:50:06 +00:00
|
|
|
goto rest_fail;
|
2009-11-19 06:36:45 +00:00
|
|
|
}
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
config_lpm:
|
2008-08-30 12:20:01 +00:00
|
|
|
/* configure link power saving */
|
2010-09-01 15:50:06 +00:00
|
|
|
if (link->lpm_policy != ap->target_lpm_policy) {
|
|
|
|
rc = ata_eh_set_lpm(link, ap->target_lpm_policy, &dev);
|
|
|
|
if (rc)
|
|
|
|
goto rest_fail;
|
|
|
|
}
|
2007-10-25 04:58:59 +00:00
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
/* this link is okay now */
|
|
|
|
ehc->i.flags = 0;
|
|
|
|
continue;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
rest_fail:
|
|
|
|
nr_fails++;
|
|
|
|
if (dev)
|
|
|
|
ata_eh_handle_dev_fail(dev, rc);
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2022-10-07 13:23:38 +00:00
|
|
|
if (ata_port_is_frozen(ap)) {
|
2007-10-09 06:06:48 +00:00
|
|
|
/* PMP reset requires working host port.
|
|
|
|
* Can't retry if it's frozen.
|
|
|
|
*/
|
2008-04-07 13:47:22 +00:00
|
|
|
if (sata_pmp_attached(ap))
|
2007-10-09 06:06:48 +00:00
|
|
|
goto out;
|
2007-08-06 09:36:24 +00:00
|
|
|
break;
|
2007-10-09 06:06:48 +00:00
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
2010-09-01 15:50:06 +00:00
|
|
|
if (nr_fails)
|
2007-08-06 09:36:24 +00:00
|
|
|
goto retry;
|
2006-05-15 11:58:22 +00:00
|
|
|
|
2007-08-06 09:36:24 +00:00
|
|
|
out:
|
|
|
|
if (rc && r_failed_link)
|
|
|
|
*r_failed_link = link;
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_finish - finish up EH
|
|
|
|
* @ap: host port to finish EH for
|
|
|
|
*
|
|
|
|
* Recovery is complete. Clean up EH states and retry or finish
|
|
|
|
* failed qcs.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* None.
|
|
|
|
*/
|
2007-09-23 04:14:12 +00:00
|
|
|
void ata_eh_finish(struct ata_port *ap)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2018-06-19 16:12:49 +00:00
|
|
|
struct ata_queued_cmd *qc;
|
2006-05-15 11:58:22 +00:00
|
|
|
int tag;
|
|
|
|
|
|
|
|
/* retry or finish qcs */
|
2018-06-19 16:12:49 +00:00
|
|
|
ata_qc_for_each_raw(ap, qc, tag) {
|
2022-12-29 16:59:57 +00:00
|
|
|
if (!(qc->flags & ATA_QCFLAG_EH))
|
2006-05-15 11:58:22 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (qc->err_mask) {
|
|
|
|
/* FIXME: Once EH migration is complete,
|
|
|
|
* generate sense data in this function,
|
|
|
|
* considering both err_mask and tf.
|
|
|
|
*/
|
2023-05-19 10:40:02 +00:00
|
|
|
if (qc->flags & ATA_QCFLAG_RETRY) {
|
|
|
|
/*
|
|
|
|
* Since qc->err_mask is set, ata_eh_qc_retry()
|
|
|
|
* will not increment scmd->allowed, so upper
|
|
|
|
* layer will only retry the command if it has
|
|
|
|
* not already been retried too many times.
|
|
|
|
*/
|
2006-05-15 11:58:22 +00:00
|
|
|
ata_eh_qc_retry(qc);
|
2023-05-19 10:40:02 +00:00
|
|
|
} else {
|
2008-03-27 10:14:24 +00:00
|
|
|
ata_eh_qc_complete(qc);
|
2023-05-19 10:40:02 +00:00
|
|
|
}
|
2006-05-15 11:58:22 +00:00
|
|
|
} else {
|
scsi: ata: libata: Handle completion of CDL commands using policy 0xD
A CDL timeout for policy 0xF is defined as a NCQ error, just with a CDL
specific sk/asc/ascq in the sense data. Therefore, the existing code in
libata does not need to be modified to handle a policy 0xF CDL timeout.
For Command Duration Limits policy 0xD:
The device shall complete the command without error with the additional
sense code set to DATA CURRENTLY UNAVAILABLE.
Since a CDL timeout for policy 0xD is not an error, we cannot use the NCQ
Command Error log (10h).
Instead, we need to read the Sense Data for Successful NCQ Commands log
(0Fh).
In the success case, just like in the error case, we cannot simply read a
log page from the interrupt handler itself, since reading a log page
involves sending a READ LOG DMA EXT or READ LOG EXT command.
Therefore, we add a new EH action ATA_EH_GET_SUCCESS_SENSE. When a command
completes without error, and when the ATA_SENSE bit is set, this new action
is set as pending, and EH is scheduled.
This way, similar to the NCQ error case, the log page will be read from EH
context.
An alternative would have been to add a new kthread or workqueue to handle
this. However, extending EH can be done with minimal changes and avoids the
need to synchronize a new kthread/workqueue with EH.
Co-developed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-20-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-11 01:13:52 +00:00
|
|
|
if (qc->flags & ATA_QCFLAG_SENSE_VALID ||
|
|
|
|
qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) {
|
2006-05-15 11:58:22 +00:00
|
|
|
ata_eh_qc_complete(qc);
|
|
|
|
} else {
|
|
|
|
/* feed zero TF to sense generation */
|
|
|
|
memset(&qc->result_tf, 0, sizeof(qc->result_tf));
|
2023-05-19 10:40:02 +00:00
|
|
|
/*
|
|
|
|
* Since qc->err_mask is not set,
|
|
|
|
* ata_eh_qc_retry() will increment
|
|
|
|
* scmd->allowed, so upper layer is guaranteed
|
|
|
|
* to retry the command.
|
|
|
|
*/
|
2006-05-15 11:58:22 +00:00
|
|
|
ata_eh_qc_retry(qc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-09-23 04:14:12 +00:00
|
|
|
|
|
|
|
/* make sure nr_active_links is zero after EH */
|
|
|
|
WARN_ON(ap->nr_active_links);
|
|
|
|
ap->nr_active_links = 0;
|
2006-05-15 11:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_do_eh - do standard error handling
|
|
|
|
* @ap: host port to handle error for
|
libata: make reset related methods proper port operations
Currently reset methods are not specified directly in the
ata_port_operations table. If a LLD wants to use custom reset
methods, it should construct and use a error_handler which uses those
reset methods. It's done this way for two reasons.
First, the ops table already contained too many methods and adding
four more of them would noticeably increase the amount of necessary
boilerplate code all over low level drivers.
Second, as ->error_handler uses those reset methods, it can get
confusing. ie. By overriding ->error_handler, those reset ops can be
made useless making layering a bit hazy.
Now that ops table uses inheritance, the first problem doesn't exist
anymore. The second isn't completely solved but is relieved by
providing default values - most drivers can just override what it has
implemented and don't have to concern itself about higher level
callbacks. In fact, there currently is no driver which actually
modifies error handling behavior. Drivers which override
->error_handler just wraps the standard error handler only to prepare
the controller for EH. I don't think making ops layering strict has
any noticeable benefit.
This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and
their PMP counterparts propoer ops. Default ops are provided in the
base ops tables and drivers are converted to override individual reset
methods instead of creating custom error_handler.
* ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs
aren't accessible. sata_promise doesn't need to use separate
error_handlers for PATA and SATA anymore.
* softreset is broken for sata_inic162x and sata_sx4. As libata now
always prefers hardreset, this doesn't really matter but the ops are
forced to NULL using ATA_OP_NULL for documentation purpose.
* pata_hpt374 needs to use different prereset for the first and second
PCI functions. This used to be done by branching from
hpt374_error_handler(). The proper way to do this is to use
separate ops and port_info tables for each function. Converted.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-03-25 03:22:50 +00:00
|
|
|
*
|
2006-05-31 09:27:48 +00:00
|
|
|
* @prereset: prereset method (can be NULL)
|
2006-05-15 11:58:22 +00:00
|
|
|
* @softreset: softreset method (can be NULL)
|
|
|
|
* @hardreset: hardreset method (can be NULL)
|
|
|
|
* @postreset: postreset method (can be NULL)
|
|
|
|
*
|
|
|
|
* Perform standard error handling sequence.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
2006-05-31 09:27:48 +00:00
|
|
|
void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|
|
|
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
|
|
|
|
ata_postreset_fn_t postreset)
|
2006-05-15 11:58:22 +00:00
|
|
|
{
|
2007-08-06 09:36:24 +00:00
|
|
|
struct ata_device *dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
ata_eh_autopsy(ap);
|
|
|
|
ata_eh_report(ap);
|
|
|
|
|
|
|
|
rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset,
|
|
|
|
NULL);
|
|
|
|
if (rc) {
|
2008-11-03 11:03:17 +00:00
|
|
|
ata_for_each_dev(dev, &ap->link, ALL)
|
2007-08-06 09:36:24 +00:00
|
|
|
ata_dev_disable(dev);
|
|
|
|
}
|
|
|
|
|
2006-05-15 11:58:22 +00:00
|
|
|
ata_eh_finish(ap);
|
|
|
|
}
|
2006-07-03 07:07:27 +00:00
|
|
|
|
libata: make reset related methods proper port operations
Currently reset methods are not specified directly in the
ata_port_operations table. If a LLD wants to use custom reset
methods, it should construct and use a error_handler which uses those
reset methods. It's done this way for two reasons.
First, the ops table already contained too many methods and adding
four more of them would noticeably increase the amount of necessary
boilerplate code all over low level drivers.
Second, as ->error_handler uses those reset methods, it can get
confusing. ie. By overriding ->error_handler, those reset ops can be
made useless making layering a bit hazy.
Now that ops table uses inheritance, the first problem doesn't exist
anymore. The second isn't completely solved but is relieved by
providing default values - most drivers can just override what it has
implemented and don't have to concern itself about higher level
callbacks. In fact, there currently is no driver which actually
modifies error handling behavior. Drivers which override
->error_handler just wraps the standard error handler only to prepare
the controller for EH. I don't think making ops layering strict has
any noticeable benefit.
This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and
their PMP counterparts propoer ops. Default ops are provided in the
base ops tables and drivers are converted to override individual reset
methods instead of creating custom error_handler.
* ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs
aren't accessible. sata_promise doesn't need to use separate
error_handlers for PATA and SATA anymore.
* softreset is broken for sata_inic162x and sata_sx4. As libata now
always prefers hardreset, this doesn't really matter but the ops are
forced to NULL using ATA_OP_NULL for documentation purpose.
* pata_hpt374 needs to use different prereset for the first and second
PCI functions. This used to be done by branching from
hpt374_error_handler(). The proper way to do this is to use
separate ops and port_info tables for each function. Converted.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-03-25 03:22:50 +00:00
|
|
|
/**
|
|
|
|
* ata_std_error_handler - standard error handler
|
|
|
|
* @ap: host port to handle error for
|
|
|
|
*
|
|
|
|
* Standard error handler
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
|
|
|
void ata_std_error_handler(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
struct ata_port_operations *ops = ap->ops;
|
|
|
|
ata_reset_fn_t hardreset = ops->hardreset;
|
|
|
|
|
2008-04-07 13:47:19 +00:00
|
|
|
/* ignore built-in hardreset if SCR access is not available */
|
2010-05-10 19:41:39 +00:00
|
|
|
if (hardreset == sata_std_hardreset && !sata_scr_valid(&ap->link))
|
libata: make reset related methods proper port operations
Currently reset methods are not specified directly in the
ata_port_operations table. If a LLD wants to use custom reset
methods, it should construct and use a error_handler which uses those
reset methods. It's done this way for two reasons.
First, the ops table already contained too many methods and adding
four more of them would noticeably increase the amount of necessary
boilerplate code all over low level drivers.
Second, as ->error_handler uses those reset methods, it can get
confusing. ie. By overriding ->error_handler, those reset ops can be
made useless making layering a bit hazy.
Now that ops table uses inheritance, the first problem doesn't exist
anymore. The second isn't completely solved but is relieved by
providing default values - most drivers can just override what it has
implemented and don't have to concern itself about higher level
callbacks. In fact, there currently is no driver which actually
modifies error handling behavior. Drivers which override
->error_handler just wraps the standard error handler only to prepare
the controller for EH. I don't think making ops layering strict has
any noticeable benefit.
This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and
their PMP counterparts propoer ops. Default ops are provided in the
base ops tables and drivers are converted to override individual reset
methods instead of creating custom error_handler.
* ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs
aren't accessible. sata_promise doesn't need to use separate
error_handlers for PATA and SATA anymore.
* softreset is broken for sata_inic162x and sata_sx4. As libata now
always prefers hardreset, this doesn't really matter but the ops are
forced to NULL using ATA_OP_NULL for documentation purpose.
* pata_hpt374 needs to use different prereset for the first and second
PCI functions. This used to be done by branching from
hpt374_error_handler(). The proper way to do this is to use
separate ops and port_info tables for each function. Converted.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-03-25 03:22:50 +00:00
|
|
|
hardreset = NULL;
|
|
|
|
|
|
|
|
ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
|
|
|
|
}
|
2020-03-26 15:58:04 +00:00
|
|
|
EXPORT_SYMBOL_GPL(ata_std_error_handler);
|
libata: make reset related methods proper port operations
Currently reset methods are not specified directly in the
ata_port_operations table. If a LLD wants to use custom reset
methods, it should construct and use a error_handler which uses those
reset methods. It's done this way for two reasons.
First, the ops table already contained too many methods and adding
four more of them would noticeably increase the amount of necessary
boilerplate code all over low level drivers.
Second, as ->error_handler uses those reset methods, it can get
confusing. ie. By overriding ->error_handler, those reset ops can be
made useless making layering a bit hazy.
Now that ops table uses inheritance, the first problem doesn't exist
anymore. The second isn't completely solved but is relieved by
providing default values - most drivers can just override what it has
implemented and don't have to concern itself about higher level
callbacks. In fact, there currently is no driver which actually
modifies error handling behavior. Drivers which override
->error_handler just wraps the standard error handler only to prepare
the controller for EH. I don't think making ops layering strict has
any noticeable benefit.
This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and
their PMP counterparts propoer ops. Default ops are provided in the
base ops tables and drivers are converted to override individual reset
methods instead of creating custom error_handler.
* ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs
aren't accessible. sata_promise doesn't need to use separate
error_handlers for PATA and SATA anymore.
* softreset is broken for sata_inic162x and sata_sx4. As libata now
always prefers hardreset, this doesn't really matter but the ops are
forced to NULL using ATA_OP_NULL for documentation purpose.
* pata_hpt374 needs to use different prereset for the first and second
PCI functions. This used to be done by branching from
hpt374_error_handler(). The proper way to do this is to use
separate ops and port_info tables for each function. Converted.
Signed-off-by: Tejun Heo <htejun@gmail.com>
2008-03-25 03:22:50 +00:00
|
|
|
|
2007-03-02 08:32:47 +00:00
|
|
|
#ifdef CONFIG_PM
|
2006-07-03 07:07:27 +00:00
|
|
|
/**
|
|
|
|
* ata_eh_handle_port_suspend - perform port suspend operation
|
|
|
|
* @ap: port to suspend
|
|
|
|
*
|
|
|
|
* Suspend @ap.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
|
|
|
static void ata_eh_handle_port_suspend(struct ata_port *ap)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
int rc = 0;
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
struct ata_device *dev;
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
struct ata_link *link;
|
2006-07-03 07:07:27 +00:00
|
|
|
|
|
|
|
/* are we suspending? */
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
|
2013-01-25 06:29:35 +00:00
|
|
|
ap->pm_mesg.event & PM_EVENT_RESUME) {
|
2006-07-03 07:07:27 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
|
|
|
WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
|
|
|
|
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
/* Set all devices attached to the port in standby mode */
|
|
|
|
ata_for_each_link(link, ap, HOST_FIRST) {
|
|
|
|
ata_for_each_dev(dev, link, ENABLED)
|
|
|
|
ata_dev_power_set_standby(dev);
|
|
|
|
}
|
|
|
|
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
/*
|
|
|
|
* If we have a ZPODD attached, check its zero
|
|
|
|
* power ready status before the port is frozen.
|
2013-01-25 06:29:35 +00:00
|
|
|
* Only needed for runtime suspend.
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
*/
|
2013-01-25 06:29:35 +00:00
|
|
|
if (PMSG_IS_AUTO(ap->pm_mesg)) {
|
|
|
|
ata_for_each_dev(dev, &ap->link, ENABLED) {
|
|
|
|
if (zpodd_dev_enabled(dev))
|
|
|
|
zpodd_on_suspend(dev);
|
|
|
|
}
|
libata: check zero power ready status for ZPODD
Per the Mount Fuji spec, the ODD is considered zero power ready when:
- For slot type ODD, no media inside;
- For tray type ODD, no media inside and tray closed.
The information can be retrieved by either the returned information of
command GET_EVENT_STATUS_NOTIFICATION(the command is used to poll for
media event) or sense code.
The information provided by the media status byte is not accurate, it
is possible that after a new disc is just inserted, the status byte
still returns media not present. So this information can not be used as
the deciding factor, we use sense code to decide if zpready status is
true.
When we first sensed the ODD in the zero power ready state, the
zp_sampled will be set and timestamp will be recoreded. And after ODD
stayed in this state for some pre-defined period, the ODD is considered
as power off ready and the zp_ready flag will be set. The zp_ready flag
serves as the deciding factor other code will use to see if power off is
OK for the ODD.
The Mount Fuji spec suggests a delay should be used here, to avoid the
case user ejects the ODD and then instantly inserts a new one again, so
that we can avoid a power transition. And some ODDs may be slow to place
its head to the home position after disc is ejected, so a delay here is
generally a good idea. And the delay time can be changed via the module
param zpodd_poweroff_delay.
The zero power ready status check is performed in the ata port's runtime
suspend code path, when port is not frozen yet, as we need to issue some
IOs to the ODD.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2013-01-15 09:21:00 +00:00
|
|
|
}
|
|
|
|
|
2006-07-03 07:07:27 +00:00
|
|
|
/* suspend */
|
|
|
|
ata_eh_freeze_port(ap);
|
|
|
|
|
|
|
|
if (ap->ops->port_suspend)
|
|
|
|
rc = ap->ops->port_suspend(ap, ap->pm_mesg);
|
|
|
|
|
2013-01-25 06:29:35 +00:00
|
|
|
ata_acpi_set_state(ap, ap->pm_mesg);
|
2022-02-01 20:50:10 +00:00
|
|
|
|
libata, libsas: kill pm_result and related cleanup
Tejun says:
"At least for libata, worrying about suspend/resume failures don't make
whole lot of sense. If suspend failed, just proceed with suspend. If
the device can't be woken up afterwards, that's that. There isn't
anything we could have done differently anyway. The same for resume, if
spinup fails, the device is dud and the following commands will invoke
EH actions and will eventually fail. Again, there really isn't any
*choice* to make. Just making sure the errors are handled gracefully
(ie. don't crash) and the following commands are handled correctly
should be enough."
The only libata user that actually cares about the result from a suspend
operation is libsas. However, it only cares about whether queuing a new
operation collides with an in-flight one. All libsas does with the
error is retry, but we can just let libata wait for the previous
operation before continuing.
Other cleanups include:
1/ Unifying all ata port pm operations on an ata_port_pm_ prefix
2/ Marking all ata port pm helper routines as returning void, only
ata_port_pm_ entry points need to fake a 0 return value.
3/ Killing ata_port_{suspend|resume}_common() in favor of calling
ata_port_request_pm() directly
4/ Killing the wrappers that just do a to_ata_port() conversion
5/ Clearly marking the entry points that do async operations with an
_async suffix.
Reference: http://marc.info/?l=linux-scsi&m=138995409532286&w=2
Cc: Phillip Susi <psusi@ubuntu.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Todd Brandt <todd.e.brandt@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-03-14 20:52:48 +00:00
|
|
|
/* update the flags */
|
2006-07-03 07:07:27 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
|
|
|
|
ap->pflags &= ~ATA_PFLAG_PM_PENDING;
|
|
|
|
if (rc == 0)
|
|
|
|
ap->pflags |= ATA_PFLAG_SUSPENDED;
|
2022-10-07 13:23:38 +00:00
|
|
|
else if (ata_port_is_frozen(ap))
|
2006-07-03 07:07:27 +00:00
|
|
|
ata_port_schedule_eh(ap);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ata_eh_handle_port_resume - perform port resume operation
|
|
|
|
* @ap: port to resume
|
|
|
|
*
|
|
|
|
* Resume @ap.
|
|
|
|
*
|
|
|
|
* LOCKING:
|
|
|
|
* Kernel thread context (may sleep).
|
|
|
|
*/
|
|
|
|
static void ata_eh_handle_port_resume(struct ata_port *ap)
|
|
|
|
{
|
2009-04-23 00:55:28 +00:00
|
|
|
struct ata_link *link;
|
|
|
|
struct ata_device *dev;
|
2006-07-03 07:07:27 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
/* are we resuming? */
|
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
|
2013-01-25 06:29:35 +00:00
|
|
|
!(ap->pm_mesg.event & PM_EVENT_RESUME)) {
|
2006-07-03 07:07:27 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
|
2007-05-04 19:27:47 +00:00
|
|
|
WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
|
2006-07-03 07:07:27 +00:00
|
|
|
|
2009-04-23 00:55:28 +00:00
|
|
|
/*
|
|
|
|
* Error timestamps are in jiffies which doesn't run while
|
|
|
|
* suspended and PHY events during resume isn't too uncommon.
|
|
|
|
* When the two are combined, it can lead to unnecessary speed
|
|
|
|
* downs if the machine is suspended and resumed repeatedly.
|
|
|
|
* Clear error history.
|
|
|
|
*/
|
|
|
|
ata_for_each_link(link, ap, HOST_FIRST)
|
|
|
|
ata_for_each_dev(dev, link, ALL)
|
|
|
|
ata_ering_clear(&dev->ering);
|
|
|
|
|
2013-01-25 06:29:35 +00:00
|
|
|
ata_acpi_set_state(ap, ap->pm_mesg);
|
2007-11-02 01:32:38 +00:00
|
|
|
|
2006-07-03 07:07:27 +00:00
|
|
|
if (ap->ops->port_resume)
|
2017-07-13 08:07:58 +00:00
|
|
|
ap->ops->port_resume(ap);
|
2006-07-03 07:07:27 +00:00
|
|
|
|
libata: reimplement ACPI invocation
This patch reimplements ACPI invocation such that, instead of
exporting ACPI details to the rest of libata, ACPI event handlers -
ata_acpi_on_resume() and ata_acpi_on_devcfg() - are used. These two
functions are responsible for determining whether specific ACPI method
is used and when.
On resume, _GTF is scheduled by setting ATA_DFLAG_ACPI_PENDING device
flag. This is done this way to avoid performing the action on wrong
device device (device swapping while suspended).
On every ata_dev_configure(), ata_acpi_on_devcfg() is called, which
performs _SDD and _GTF. _GTF is performed only after resuming and, if
SATA, hardreset as the ACPI spec specifies. As _GTF may contain
arbitrary commands, IDENTIFY page is re-read after _GTF taskfiles are
executed.
If one of ACPI methods fails, ata_acpi_on_devcfg() retries on the
first failure. If it fails again on the second try, ACPI is disabled
on the device. Note that successful configuration clears ACPI failed
status.
With all feature checks moved to the above two functions,
do_drive_set_taskfiles() is trivial and thus collapsed into
ata_acpi_exec_tfs(), which is now static and converted to return the
number of executed taskfiles to be used by ata_acpi_on_resume(). As
failures are handled properly, ata_acpi_push_id() now returns -errno
on errors instead of unconditional zero.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-05-14 18:28:16 +00:00
|
|
|
/* tell ACPI that we're resuming */
|
|
|
|
ata_acpi_on_resume(ap);
|
|
|
|
|
libata, libsas: kill pm_result and related cleanup
Tejun says:
"At least for libata, worrying about suspend/resume failures don't make
whole lot of sense. If suspend failed, just proceed with suspend. If
the device can't be woken up afterwards, that's that. There isn't
anything we could have done differently anyway. The same for resume, if
spinup fails, the device is dud and the following commands will invoke
EH actions and will eventually fail. Again, there really isn't any
*choice* to make. Just making sure the errors are handled gracefully
(ie. don't crash) and the following commands are handled correctly
should be enough."
The only libata user that actually cares about the result from a suspend
operation is libsas. However, it only cares about whether queuing a new
operation collides with an in-flight one. All libsas does with the
error is retry, but we can just let libata wait for the previous
operation before continuing.
Other cleanups include:
1/ Unifying all ata port pm operations on an ata_port_pm_ prefix
2/ Marking all ata port pm helper routines as returning void, only
ata_port_pm_ entry points need to fake a 0 return value.
3/ Killing ata_port_{suspend|resume}_common() in favor of calling
ata_port_request_pm() directly
4/ Killing the wrappers that just do a to_ata_port() conversion
5/ Clearly marking the entry points that do async operations with an
_async suffix.
Reference: http://marc.info/?l=linux-scsi&m=138995409532286&w=2
Cc: Phillip Susi <psusi@ubuntu.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Todd Brandt <todd.e.brandt@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-03-14 20:52:48 +00:00
|
|
|
/* update the flags */
|
2006-07-03 07:07:27 +00:00
|
|
|
spin_lock_irqsave(ap->lock, flags);
|
|
|
|
ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
|
ata: libata-scsi: Disable scsi device manage_system_start_stop
The introduction of a device link to create a consumer/supplier
relationship between the scsi device of an ATA device and the ATA port
of that ATA device fixes the ordering of system suspend and resume
operations. For suspend, the scsi device is suspended first and the ata
port after it. This is fine as this allows the synchronize cache and
START STOP UNIT commands issued by the scsi disk driver to be executed
before the ata port is disabled.
For resume operations, the ata port is resumed first, followed
by the scsi device. This allows having the request queue of the scsi
device to be unfrozen after the ata port resume is scheduled in EH,
thus avoiding to see new requests prematurely issued to the ATA device.
Since libata sets manage_system_start_stop to 1, the scsi disk resume
operation also results in issuing a START STOP UNIT command to the
device being resumed so that the device exits standby power mode.
However, restoring the ATA device to the active power mode must be
synchronized with libata EH processing of the port resume operation to
avoid either 1) seeing the start stop unit command being received too
early when the port is not yet resumed and ready to accept commands, or
after the port resume process issues commands such as IDENTIFY to
revalidate the device. In this last case, the risk is that the device
revalidation fails with timeout errors as the drive is still spun down.
Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
disabled issuing the START STOP UNIT command to avoid issues with it.
But this is incorrect as transitioning a device to the active power
mode from the standby power mode set on suspend requires a media access
command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
libata EH context triggered by the ata port resume operation may thus
fail.
Fix these synchronization issues is by handling a device power mode
transitions for system suspend and resume directly in libata EH context,
without relying on the scsi disk driver management triggered with the
manage_system_start_stop flag.
To do this, the following libata helper functions are introduced:
1) ata_dev_power_set_standby():
This function issues a STANDBY IMMEDIATE command to transitiom a device
to the standby power mode. For HDDs, this spins down the disks. This
function applies only to ATA and ZAC devices and does nothing otherwise.
This function also does nothing for devices that have the
ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
set.
For suspend, call ata_dev_power_set_standby() in
ata_eh_handle_port_suspend() before the port is disabled and frozen.
ata_eh_unload() is also modified to transition all enabled devices to
the standby power mode when the system is shutdown or devices removed.
2) ata_dev_power_set_active() and
This function applies to ATA or ZAC devices and issues a VERIFY command
for 1 sector at LBA 0 to transition the device to the active power mode.
For HDDs, since this function will complete only once the disk spin up.
Its execution uses the same timeouts as for reset, to give the drive
enough time to complete spinup without triggering a command timeout.
For resume, call ata_dev_power_set_active() in
ata_eh_revalidate_and_attach() after the port has been enabled and
before any other command is issued to the device.
With these changes, the manage_system_start_stop and no_start_on_resume
scsi device flags do not need to be set in ata_scsi_dev_config(). The
flag manage_runtime_start_stop is still set to allow the sd driver to
spinup/spindown a disk through the sd runtime operations.
Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-08-26 00:43:39 +00:00
|
|
|
ap->pflags |= ATA_PFLAG_RESUMING;
|
2006-07-03 07:07:27 +00:00
|
|
|
spin_unlock_irqrestore(ap->lock, flags);
|
|
|
|
}
|
2007-03-02 08:32:47 +00:00
|
|
|
#endif /* CONFIG_PM */
|