162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * libata-eh.c - libata error handling 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2006 Tejun Heo <htejun@gmail.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * libata documentation is available via 'make {ps|pdf}docs', 862306a36Sopenharmony_ci * as Documentation/driver-api/libata.rst 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Hardware documentation available from http://www.t13.org/ and 1162306a36Sopenharmony_ci * http://www.sata-io.org/ 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/blkdev.h> 1662306a36Sopenharmony_ci#include <linux/export.h> 1762306a36Sopenharmony_ci#include <linux/pci.h> 1862306a36Sopenharmony_ci#include <scsi/scsi.h> 1962306a36Sopenharmony_ci#include <scsi/scsi_host.h> 2062306a36Sopenharmony_ci#include <scsi/scsi_eh.h> 2162306a36Sopenharmony_ci#include <scsi/scsi_device.h> 2262306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h> 2362306a36Sopenharmony_ci#include <scsi/scsi_dbg.h> 2462306a36Sopenharmony_ci#include "../scsi/scsi_transport_api.h" 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <linux/libata.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <trace/events/libata.h> 2962306a36Sopenharmony_ci#include "libata.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cienum { 3262306a36Sopenharmony_ci /* speed down verdicts */ 3362306a36Sopenharmony_ci ATA_EH_SPDN_NCQ_OFF = (1 << 0), 3462306a36Sopenharmony_ci ATA_EH_SPDN_SPEED_DOWN = (1 << 1), 3562306a36Sopenharmony_ci ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2), 3662306a36Sopenharmony_ci ATA_EH_SPDN_KEEP_ERRORS = (1 << 3), 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci /* error flags */ 3962306a36Sopenharmony_ci ATA_EFLAG_IS_IO = (1 << 0), 4062306a36Sopenharmony_ci ATA_EFLAG_DUBIOUS_XFER = (1 << 1), 4162306a36Sopenharmony_ci ATA_EFLAG_OLD_ER = (1 << 31), 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* error categories */ 4462306a36Sopenharmony_ci ATA_ECAT_NONE = 0, 4562306a36Sopenharmony_ci ATA_ECAT_ATA_BUS = 1, 4662306a36Sopenharmony_ci ATA_ECAT_TOUT_HSM = 2, 4762306a36Sopenharmony_ci ATA_ECAT_UNK_DEV = 3, 4862306a36Sopenharmony_ci ATA_ECAT_DUBIOUS_NONE = 4, 4962306a36Sopenharmony_ci ATA_ECAT_DUBIOUS_ATA_BUS = 5, 5062306a36Sopenharmony_ci ATA_ECAT_DUBIOUS_TOUT_HSM = 6, 5162306a36Sopenharmony_ci ATA_ECAT_DUBIOUS_UNK_DEV = 7, 5262306a36Sopenharmony_ci ATA_ECAT_NR = 8, 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci ATA_EH_CMD_DFL_TIMEOUT = 5000, 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* always put at least this amount of time between resets */ 5762306a36Sopenharmony_ci ATA_EH_RESET_COOL_DOWN = 5000, 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci /* Waiting in ->prereset can never be reliable. It's 6062306a36Sopenharmony_ci * sometimes nice to wait there but it can't be depended upon; 6162306a36Sopenharmony_ci * otherwise, we wouldn't be resetting. Just give it enough 6262306a36Sopenharmony_ci * time for most drives to spin up. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ci ATA_EH_PRERESET_TIMEOUT = 10000, 6562306a36Sopenharmony_ci ATA_EH_FASTDRAIN_INTERVAL = 3000, 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci ATA_EH_UA_TRIES = 5, 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci /* probe speed down parameters, see ata_eh_schedule_probe() */ 7062306a36Sopenharmony_ci ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */ 7162306a36Sopenharmony_ci ATA_EH_PROBE_TRIALS = 2, 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/* The following table determines how we sequence resets. Each entry 7562306a36Sopenharmony_ci * represents timeout for that try. The first try can be soft or 7662306a36Sopenharmony_ci * hardreset. All others are hardreset if available. In most cases 7762306a36Sopenharmony_ci * the first reset w/ 10sec timeout should succeed. Following entries 7862306a36Sopenharmony_ci * are mostly for error handling, hotplug and those outlier devices that 7962306a36Sopenharmony_ci * take an exceptionally long time to recover from reset. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_cistatic const unsigned int ata_eh_reset_timeouts[] = { 8262306a36Sopenharmony_ci 10000, /* most drives spin up by 10sec */ 8362306a36Sopenharmony_ci 10000, /* > 99% working drives spin up before 20sec */ 8462306a36Sopenharmony_ci 35000, /* give > 30 secs of idleness for outlier devices */ 8562306a36Sopenharmony_ci 5000, /* and sweet one last chance */ 8662306a36Sopenharmony_ci UINT_MAX, /* > 1 min has elapsed, give up */ 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic const unsigned int ata_eh_identify_timeouts[] = { 9062306a36Sopenharmony_ci 5000, /* covers > 99% of successes and not too boring on failures */ 9162306a36Sopenharmony_ci 10000, /* combined time till here is enough even for media access */ 9262306a36Sopenharmony_ci 30000, /* for true idiots */ 9362306a36Sopenharmony_ci UINT_MAX, 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic const unsigned int ata_eh_revalidate_timeouts[] = { 9762306a36Sopenharmony_ci 15000, /* Some drives are slow to read log pages when waking-up */ 9862306a36Sopenharmony_ci 15000, /* combined time till here is enough even for media access */ 9962306a36Sopenharmony_ci UINT_MAX, 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic const unsigned int ata_eh_flush_timeouts[] = { 10362306a36Sopenharmony_ci 15000, /* be generous with flush */ 10462306a36Sopenharmony_ci 15000, /* ditto */ 10562306a36Sopenharmony_ci 30000, /* and even more generous */ 10662306a36Sopenharmony_ci UINT_MAX, 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic const unsigned int ata_eh_other_timeouts[] = { 11062306a36Sopenharmony_ci 5000, /* same rationale as identify timeout */ 11162306a36Sopenharmony_ci 10000, /* ditto */ 11262306a36Sopenharmony_ci /* but no merciful 30sec for other commands, it just isn't worth it */ 11362306a36Sopenharmony_ci UINT_MAX, 11462306a36Sopenharmony_ci}; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistruct ata_eh_cmd_timeout_ent { 11762306a36Sopenharmony_ci const u8 *commands; 11862306a36Sopenharmony_ci const unsigned int *timeouts; 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* The following table determines timeouts to use for EH internal 12262306a36Sopenharmony_ci * commands. Each table entry is a command class and matches the 12362306a36Sopenharmony_ci * commands the entry applies to and the timeout table to use. 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * On the retry after a command timed out, the next timeout value from 12662306a36Sopenharmony_ci * the table is used. If the table doesn't contain further entries, 12762306a36Sopenharmony_ci * the last value is used. 12862306a36Sopenharmony_ci * 12962306a36Sopenharmony_ci * ehc->cmd_timeout_idx keeps track of which timeout to use per 13062306a36Sopenharmony_ci * command class, so if SET_FEATURES times out on the first try, the 13162306a36Sopenharmony_ci * next try will use the second timeout value only for that class. 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci#define CMDS(cmds...) (const u8 []){ cmds, 0 } 13462306a36Sopenharmony_cistatic const struct ata_eh_cmd_timeout_ent 13562306a36Sopenharmony_ciata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { 13662306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), 13762306a36Sopenharmony_ci .timeouts = ata_eh_identify_timeouts, }, 13862306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), 13962306a36Sopenharmony_ci .timeouts = ata_eh_revalidate_timeouts, }, 14062306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), 14162306a36Sopenharmony_ci .timeouts = ata_eh_other_timeouts, }, 14262306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), 14362306a36Sopenharmony_ci .timeouts = ata_eh_other_timeouts, }, 14462306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_SET_FEATURES), 14562306a36Sopenharmony_ci .timeouts = ata_eh_other_timeouts, }, 14662306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS), 14762306a36Sopenharmony_ci .timeouts = ata_eh_other_timeouts, }, 14862306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), 14962306a36Sopenharmony_ci .timeouts = ata_eh_flush_timeouts }, 15062306a36Sopenharmony_ci { .commands = CMDS(ATA_CMD_VERIFY), 15162306a36Sopenharmony_ci .timeouts = ata_eh_reset_timeouts }, 15262306a36Sopenharmony_ci}; 15362306a36Sopenharmony_ci#undef CMDS 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic void __ata_port_freeze(struct ata_port *ap); 15662306a36Sopenharmony_cistatic int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, 15762306a36Sopenharmony_ci struct ata_device **r_failed_dev); 15862306a36Sopenharmony_ci#ifdef CONFIG_PM 15962306a36Sopenharmony_cistatic void ata_eh_handle_port_suspend(struct ata_port *ap); 16062306a36Sopenharmony_cistatic void ata_eh_handle_port_resume(struct ata_port *ap); 16162306a36Sopenharmony_ci#else /* CONFIG_PM */ 16262306a36Sopenharmony_cistatic void ata_eh_handle_port_suspend(struct ata_port *ap) 16362306a36Sopenharmony_ci{ } 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic void ata_eh_handle_port_resume(struct ata_port *ap) 16662306a36Sopenharmony_ci{ } 16762306a36Sopenharmony_ci#endif /* CONFIG_PM */ 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic __printf(2, 0) void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, 17062306a36Sopenharmony_ci const char *fmt, va_list args) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, 17362306a36Sopenharmony_ci ATA_EH_DESC_LEN - ehi->desc_len, 17462306a36Sopenharmony_ci fmt, args); 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/** 17862306a36Sopenharmony_ci * __ata_ehi_push_desc - push error description without adding separator 17962306a36Sopenharmony_ci * @ehi: target EHI 18062306a36Sopenharmony_ci * @fmt: printf format string 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * Format string according to @fmt and append it to @ehi->desc. 18362306a36Sopenharmony_ci * 18462306a36Sopenharmony_ci * LOCKING: 18562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_civoid __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci va_list args; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci va_start(args, fmt); 19262306a36Sopenharmony_ci __ata_ehi_pushv_desc(ehi, fmt, args); 19362306a36Sopenharmony_ci va_end(args); 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__ata_ehi_push_desc); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/** 19862306a36Sopenharmony_ci * ata_ehi_push_desc - push error description with separator 19962306a36Sopenharmony_ci * @ehi: target EHI 20062306a36Sopenharmony_ci * @fmt: printf format string 20162306a36Sopenharmony_ci * 20262306a36Sopenharmony_ci * Format string according to @fmt and append it to @ehi->desc. 20362306a36Sopenharmony_ci * If @ehi->desc is not empty, ", " is added in-between. 20462306a36Sopenharmony_ci * 20562306a36Sopenharmony_ci * LOCKING: 20662306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 20762306a36Sopenharmony_ci */ 20862306a36Sopenharmony_civoid ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci va_list args; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (ehi->desc_len) 21362306a36Sopenharmony_ci __ata_ehi_push_desc(ehi, ", "); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci va_start(args, fmt); 21662306a36Sopenharmony_ci __ata_ehi_pushv_desc(ehi, fmt, args); 21762306a36Sopenharmony_ci va_end(args); 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_ehi_push_desc); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci/** 22262306a36Sopenharmony_ci * ata_ehi_clear_desc - clean error description 22362306a36Sopenharmony_ci * @ehi: target EHI 22462306a36Sopenharmony_ci * 22562306a36Sopenharmony_ci * Clear @ehi->desc. 22662306a36Sopenharmony_ci * 22762306a36Sopenharmony_ci * LOCKING: 22862306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 22962306a36Sopenharmony_ci */ 23062306a36Sopenharmony_civoid ata_ehi_clear_desc(struct ata_eh_info *ehi) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci ehi->desc[0] = '\0'; 23362306a36Sopenharmony_ci ehi->desc_len = 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_ehi_clear_desc); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci/** 23862306a36Sopenharmony_ci * ata_port_desc - append port description 23962306a36Sopenharmony_ci * @ap: target ATA port 24062306a36Sopenharmony_ci * @fmt: printf format string 24162306a36Sopenharmony_ci * 24262306a36Sopenharmony_ci * Format string according to @fmt and append it to port 24362306a36Sopenharmony_ci * description. If port description is not empty, " " is added 24462306a36Sopenharmony_ci * in-between. This function is to be used while initializing 24562306a36Sopenharmony_ci * ata_host. The description is printed on host registration. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * LOCKING: 24862306a36Sopenharmony_ci * None. 24962306a36Sopenharmony_ci */ 25062306a36Sopenharmony_civoid ata_port_desc(struct ata_port *ap, const char *fmt, ...) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci va_list args; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING)); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (ap->link.eh_info.desc_len) 25762306a36Sopenharmony_ci __ata_ehi_push_desc(&ap->link.eh_info, " "); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci va_start(args, fmt); 26062306a36Sopenharmony_ci __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); 26162306a36Sopenharmony_ci va_end(args); 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_desc); 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci#ifdef CONFIG_PCI 26662306a36Sopenharmony_ci/** 26762306a36Sopenharmony_ci * ata_port_pbar_desc - append PCI BAR description 26862306a36Sopenharmony_ci * @ap: target ATA port 26962306a36Sopenharmony_ci * @bar: target PCI BAR 27062306a36Sopenharmony_ci * @offset: offset into PCI BAR 27162306a36Sopenharmony_ci * @name: name of the area 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * If @offset is negative, this function formats a string which 27462306a36Sopenharmony_ci * contains the name, address, size and type of the BAR and 27562306a36Sopenharmony_ci * appends it to the port description. If @offset is zero or 27662306a36Sopenharmony_ci * positive, only name and offsetted address is appended. 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * LOCKING: 27962306a36Sopenharmony_ci * None. 28062306a36Sopenharmony_ci */ 28162306a36Sopenharmony_civoid ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, 28262306a36Sopenharmony_ci const char *name) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(ap->host->dev); 28562306a36Sopenharmony_ci char *type = ""; 28662306a36Sopenharmony_ci unsigned long long start, len; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) 28962306a36Sopenharmony_ci type = "m"; 29062306a36Sopenharmony_ci else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) 29162306a36Sopenharmony_ci type = "i"; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci start = (unsigned long long)pci_resource_start(pdev, bar); 29462306a36Sopenharmony_ci len = (unsigned long long)pci_resource_len(pdev, bar); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci if (offset < 0) 29762306a36Sopenharmony_ci ata_port_desc(ap, "%s %s%llu@0x%llx", name, type, len, start); 29862306a36Sopenharmony_ci else 29962306a36Sopenharmony_ci ata_port_desc(ap, "%s 0x%llx", name, 30062306a36Sopenharmony_ci start + (unsigned long long)offset); 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_pbar_desc); 30362306a36Sopenharmony_ci#endif /* CONFIG_PCI */ 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_cistatic int ata_lookup_timeout_table(u8 cmd) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci int i; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci for (i = 0; i < ATA_EH_CMD_TIMEOUT_TABLE_SIZE; i++) { 31062306a36Sopenharmony_ci const u8 *cur; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci for (cur = ata_eh_cmd_timeout_table[i].commands; *cur; cur++) 31362306a36Sopenharmony_ci if (*cur == cmd) 31462306a36Sopenharmony_ci return i; 31562306a36Sopenharmony_ci } 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci return -1; 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci/** 32162306a36Sopenharmony_ci * ata_internal_cmd_timeout - determine timeout for an internal command 32262306a36Sopenharmony_ci * @dev: target device 32362306a36Sopenharmony_ci * @cmd: internal command to be issued 32462306a36Sopenharmony_ci * 32562306a36Sopenharmony_ci * Determine timeout for internal command @cmd for @dev. 32662306a36Sopenharmony_ci * 32762306a36Sopenharmony_ci * LOCKING: 32862306a36Sopenharmony_ci * EH context. 32962306a36Sopenharmony_ci * 33062306a36Sopenharmony_ci * RETURNS: 33162306a36Sopenharmony_ci * Determined timeout. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ciunsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 33662306a36Sopenharmony_ci int ent = ata_lookup_timeout_table(cmd); 33762306a36Sopenharmony_ci int idx; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci if (ent < 0) 34062306a36Sopenharmony_ci return ATA_EH_CMD_DFL_TIMEOUT; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci idx = ehc->cmd_timeout_idx[dev->devno][ent]; 34362306a36Sopenharmony_ci return ata_eh_cmd_timeout_table[ent].timeouts[idx]; 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/** 34762306a36Sopenharmony_ci * ata_internal_cmd_timed_out - notification for internal command timeout 34862306a36Sopenharmony_ci * @dev: target device 34962306a36Sopenharmony_ci * @cmd: internal command which timed out 35062306a36Sopenharmony_ci * 35162306a36Sopenharmony_ci * Notify EH that internal command @cmd for @dev timed out. This 35262306a36Sopenharmony_ci * function should be called only for commands whose timeouts are 35362306a36Sopenharmony_ci * determined using ata_internal_cmd_timeout(). 35462306a36Sopenharmony_ci * 35562306a36Sopenharmony_ci * LOCKING: 35662306a36Sopenharmony_ci * EH context. 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_civoid ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 36162306a36Sopenharmony_ci int ent = ata_lookup_timeout_table(cmd); 36262306a36Sopenharmony_ci int idx; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if (ent < 0) 36562306a36Sopenharmony_ci return; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci idx = ehc->cmd_timeout_idx[dev->devno][ent]; 36862306a36Sopenharmony_ci if (ata_eh_cmd_timeout_table[ent].timeouts[idx + 1] != UINT_MAX) 36962306a36Sopenharmony_ci ehc->cmd_timeout_idx[dev->devno][ent]++; 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cistatic void ata_ering_record(struct ata_ering *ering, unsigned int eflags, 37362306a36Sopenharmony_ci unsigned int err_mask) 37462306a36Sopenharmony_ci{ 37562306a36Sopenharmony_ci struct ata_ering_entry *ent; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci WARN_ON(!err_mask); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci ering->cursor++; 38062306a36Sopenharmony_ci ering->cursor %= ATA_ERING_SIZE; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci ent = &ering->ring[ering->cursor]; 38362306a36Sopenharmony_ci ent->eflags = eflags; 38462306a36Sopenharmony_ci ent->err_mask = err_mask; 38562306a36Sopenharmony_ci ent->timestamp = get_jiffies_64(); 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistatic struct ata_ering_entry *ata_ering_top(struct ata_ering *ering) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci struct ata_ering_entry *ent = &ering->ring[ering->cursor]; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci if (ent->err_mask) 39362306a36Sopenharmony_ci return ent; 39462306a36Sopenharmony_ci return NULL; 39562306a36Sopenharmony_ci} 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ciint ata_ering_map(struct ata_ering *ering, 39862306a36Sopenharmony_ci int (*map_fn)(struct ata_ering_entry *, void *), 39962306a36Sopenharmony_ci void *arg) 40062306a36Sopenharmony_ci{ 40162306a36Sopenharmony_ci int idx, rc = 0; 40262306a36Sopenharmony_ci struct ata_ering_entry *ent; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci idx = ering->cursor; 40562306a36Sopenharmony_ci do { 40662306a36Sopenharmony_ci ent = &ering->ring[idx]; 40762306a36Sopenharmony_ci if (!ent->err_mask) 40862306a36Sopenharmony_ci break; 40962306a36Sopenharmony_ci rc = map_fn(ent, arg); 41062306a36Sopenharmony_ci if (rc) 41162306a36Sopenharmony_ci break; 41262306a36Sopenharmony_ci idx = (idx - 1 + ATA_ERING_SIZE) % ATA_ERING_SIZE; 41362306a36Sopenharmony_ci } while (idx != ering->cursor); 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci return rc; 41662306a36Sopenharmony_ci} 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_cistatic int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg) 41962306a36Sopenharmony_ci{ 42062306a36Sopenharmony_ci ent->eflags |= ATA_EFLAG_OLD_ER; 42162306a36Sopenharmony_ci return 0; 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic void ata_ering_clear(struct ata_ering *ering) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci ata_ering_map(ering, ata_ering_clear_cb, NULL); 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic unsigned int ata_eh_dev_action(struct ata_device *dev) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci return ehc->i.action | ehc->i.dev_action[dev->devno]; 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev, 43762306a36Sopenharmony_ci struct ata_eh_info *ehi, unsigned int action) 43862306a36Sopenharmony_ci{ 43962306a36Sopenharmony_ci struct ata_device *tdev; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci if (!dev) { 44262306a36Sopenharmony_ci ehi->action &= ~action; 44362306a36Sopenharmony_ci ata_for_each_dev(tdev, link, ALL) 44462306a36Sopenharmony_ci ehi->dev_action[tdev->devno] &= ~action; 44562306a36Sopenharmony_ci } else { 44662306a36Sopenharmony_ci /* doesn't make sense for port-wide EH actions */ 44762306a36Sopenharmony_ci WARN_ON(!(action & ATA_EH_PERDEV_MASK)); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci /* break ehi->action into ehi->dev_action */ 45062306a36Sopenharmony_ci if (ehi->action & action) { 45162306a36Sopenharmony_ci ata_for_each_dev(tdev, link, ALL) 45262306a36Sopenharmony_ci ehi->dev_action[tdev->devno] |= 45362306a36Sopenharmony_ci ehi->action & action; 45462306a36Sopenharmony_ci ehi->action &= ~action; 45562306a36Sopenharmony_ci } 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* turn off the specified per-dev action */ 45862306a36Sopenharmony_ci ehi->dev_action[dev->devno] &= ~action; 45962306a36Sopenharmony_ci } 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci/** 46362306a36Sopenharmony_ci * ata_eh_acquire - acquire EH ownership 46462306a36Sopenharmony_ci * @ap: ATA port to acquire EH ownership for 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * Acquire EH ownership for @ap. This is the basic exclusion 46762306a36Sopenharmony_ci * mechanism for ports sharing a host. Only one port hanging off 46862306a36Sopenharmony_ci * the same host can claim the ownership of EH. 46962306a36Sopenharmony_ci * 47062306a36Sopenharmony_ci * LOCKING: 47162306a36Sopenharmony_ci * EH context. 47262306a36Sopenharmony_ci */ 47362306a36Sopenharmony_civoid ata_eh_acquire(struct ata_port *ap) 47462306a36Sopenharmony_ci{ 47562306a36Sopenharmony_ci mutex_lock(&ap->host->eh_mutex); 47662306a36Sopenharmony_ci WARN_ON_ONCE(ap->host->eh_owner); 47762306a36Sopenharmony_ci ap->host->eh_owner = current; 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci/** 48162306a36Sopenharmony_ci * ata_eh_release - release EH ownership 48262306a36Sopenharmony_ci * @ap: ATA port to release EH ownership for 48362306a36Sopenharmony_ci * 48462306a36Sopenharmony_ci * Release EH ownership for @ap if the caller. The caller must 48562306a36Sopenharmony_ci * have acquired EH ownership using ata_eh_acquire() previously. 48662306a36Sopenharmony_ci * 48762306a36Sopenharmony_ci * LOCKING: 48862306a36Sopenharmony_ci * EH context. 48962306a36Sopenharmony_ci */ 49062306a36Sopenharmony_civoid ata_eh_release(struct ata_port *ap) 49162306a36Sopenharmony_ci{ 49262306a36Sopenharmony_ci WARN_ON_ONCE(ap->host->eh_owner != current); 49362306a36Sopenharmony_ci ap->host->eh_owner = NULL; 49462306a36Sopenharmony_ci mutex_unlock(&ap->host->eh_mutex); 49562306a36Sopenharmony_ci} 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_cistatic void ata_eh_unload(struct ata_port *ap) 49862306a36Sopenharmony_ci{ 49962306a36Sopenharmony_ci struct ata_link *link; 50062306a36Sopenharmony_ci struct ata_device *dev; 50162306a36Sopenharmony_ci unsigned long flags; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci /* 50462306a36Sopenharmony_ci * Unless we are restarting, transition all enabled devices to 50562306a36Sopenharmony_ci * standby power mode. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_ci if (system_state != SYSTEM_RESTART) { 50862306a36Sopenharmony_ci ata_for_each_link(link, ap, PMP_FIRST) { 50962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) 51062306a36Sopenharmony_ci ata_dev_power_set_standby(dev); 51162306a36Sopenharmony_ci } 51262306a36Sopenharmony_ci } 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci /* 51562306a36Sopenharmony_ci * Restore SControl IPM and SPD for the next driver and 51662306a36Sopenharmony_ci * disable attached devices. 51762306a36Sopenharmony_ci */ 51862306a36Sopenharmony_ci ata_for_each_link(link, ap, PMP_FIRST) { 51962306a36Sopenharmony_ci sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0); 52062306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 52162306a36Sopenharmony_ci ata_dev_disable(dev); 52262306a36Sopenharmony_ci } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* freeze and set UNLOADED */ 52562306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci ata_port_freeze(ap); /* won't be thawed */ 52862306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_EH_PENDING; /* clear pending from freeze */ 52962306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_UNLOADED; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 53262306a36Sopenharmony_ci} 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci/** 53562306a36Sopenharmony_ci * ata_scsi_error - SCSI layer error handler callback 53662306a36Sopenharmony_ci * @host: SCSI host on which error occurred 53762306a36Sopenharmony_ci * 53862306a36Sopenharmony_ci * Handles SCSI-layer-thrown error events. 53962306a36Sopenharmony_ci * 54062306a36Sopenharmony_ci * LOCKING: 54162306a36Sopenharmony_ci * Inherited from SCSI layer (none, can sleep) 54262306a36Sopenharmony_ci * 54362306a36Sopenharmony_ci * RETURNS: 54462306a36Sopenharmony_ci * Zero. 54562306a36Sopenharmony_ci */ 54662306a36Sopenharmony_civoid ata_scsi_error(struct Scsi_Host *host) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(host); 54962306a36Sopenharmony_ci unsigned long flags; 55062306a36Sopenharmony_ci LIST_HEAD(eh_work_q); 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci spin_lock_irqsave(host->host_lock, flags); 55362306a36Sopenharmony_ci list_splice_init(&host->eh_cmd_q, &eh_work_q); 55462306a36Sopenharmony_ci spin_unlock_irqrestore(host->host_lock, flags); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci ata_scsi_cmd_error_handler(host, ap, &eh_work_q); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci /* If we timed raced normal completion and there is nothing to 55962306a36Sopenharmony_ci recover nr_timedout == 0 why exactly are we doing error recovery ? */ 56062306a36Sopenharmony_ci ata_scsi_port_error_handler(host, ap); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci /* finish or retry handled scmd's and clean up */ 56362306a36Sopenharmony_ci WARN_ON(!list_empty(&eh_work_q)); 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci} 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci/** 56862306a36Sopenharmony_ci * ata_scsi_cmd_error_handler - error callback for a list of commands 56962306a36Sopenharmony_ci * @host: scsi host containing the port 57062306a36Sopenharmony_ci * @ap: ATA port within the host 57162306a36Sopenharmony_ci * @eh_work_q: list of commands to process 57262306a36Sopenharmony_ci * 57362306a36Sopenharmony_ci * process the given list of commands and return those finished to the 57462306a36Sopenharmony_ci * ap->eh_done_q. This function is the first part of the libata error 57562306a36Sopenharmony_ci * handler which processes a given list of failed commands. 57662306a36Sopenharmony_ci */ 57762306a36Sopenharmony_civoid ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, 57862306a36Sopenharmony_ci struct list_head *eh_work_q) 57962306a36Sopenharmony_ci{ 58062306a36Sopenharmony_ci int i; 58162306a36Sopenharmony_ci unsigned long flags; 58262306a36Sopenharmony_ci struct scsi_cmnd *scmd, *tmp; 58362306a36Sopenharmony_ci int nr_timedout = 0; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci /* make sure sff pio task is not running */ 58662306a36Sopenharmony_ci ata_sff_flush_pio_task(ap); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci /* synchronize with host lock and sort out timeouts */ 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci /* 59162306a36Sopenharmony_ci * For EH, all qcs are finished in one of three ways - 59262306a36Sopenharmony_ci * normal completion, error completion, and SCSI timeout. 59362306a36Sopenharmony_ci * Both completions can race against SCSI timeout. When normal 59462306a36Sopenharmony_ci * completion wins, the qc never reaches EH. When error 59562306a36Sopenharmony_ci * completion wins, the qc has ATA_QCFLAG_EH set. 59662306a36Sopenharmony_ci * 59762306a36Sopenharmony_ci * When SCSI timeout wins, things are a bit more complex. 59862306a36Sopenharmony_ci * Normal or error completion can occur after the timeout but 59962306a36Sopenharmony_ci * before this point. In such cases, both types of 60062306a36Sopenharmony_ci * completions are honored. A scmd is determined to have 60162306a36Sopenharmony_ci * timed out iff its associated qc is active and not failed. 60262306a36Sopenharmony_ci */ 60362306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci /* 60662306a36Sopenharmony_ci * This must occur under the ap->lock as we don't want 60762306a36Sopenharmony_ci * a polled recovery to race the real interrupt handler 60862306a36Sopenharmony_ci * 60962306a36Sopenharmony_ci * The lost_interrupt handler checks for any completed but 61062306a36Sopenharmony_ci * non-notified command and completes much like an IRQ handler. 61162306a36Sopenharmony_ci * 61262306a36Sopenharmony_ci * We then fall into the error recovery code which will treat 61362306a36Sopenharmony_ci * this as if normal completion won the race 61462306a36Sopenharmony_ci */ 61562306a36Sopenharmony_ci if (ap->ops->lost_interrupt) 61662306a36Sopenharmony_ci ap->ops->lost_interrupt(ap); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) { 61962306a36Sopenharmony_ci struct ata_queued_cmd *qc; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, i) { 62262306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_ACTIVE && 62362306a36Sopenharmony_ci qc->scsicmd == scmd) 62462306a36Sopenharmony_ci break; 62562306a36Sopenharmony_ci } 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci if (i < ATA_MAX_QUEUE) { 62862306a36Sopenharmony_ci /* the scmd has an associated qc */ 62962306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH)) { 63062306a36Sopenharmony_ci /* which hasn't failed yet, timeout */ 63162306a36Sopenharmony_ci qc->err_mask |= AC_ERR_TIMEOUT; 63262306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_EH; 63362306a36Sopenharmony_ci nr_timedout++; 63462306a36Sopenharmony_ci } 63562306a36Sopenharmony_ci } else { 63662306a36Sopenharmony_ci /* Normal completion occurred after 63762306a36Sopenharmony_ci * SCSI timeout but before this point. 63862306a36Sopenharmony_ci * Successfully complete it. 63962306a36Sopenharmony_ci */ 64062306a36Sopenharmony_ci scmd->retries = scmd->allowed; 64162306a36Sopenharmony_ci scsi_eh_finish_cmd(scmd, &ap->eh_done_q); 64262306a36Sopenharmony_ci } 64362306a36Sopenharmony_ci } 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci /* 64662306a36Sopenharmony_ci * If we have timed out qcs. They belong to EH from 64762306a36Sopenharmony_ci * this point but the state of the controller is 64862306a36Sopenharmony_ci * unknown. Freeze the port to make sure the IRQ 64962306a36Sopenharmony_ci * handler doesn't diddle with those qcs. This must 65062306a36Sopenharmony_ci * be done atomically w.r.t. setting ATA_QCFLAG_EH. 65162306a36Sopenharmony_ci */ 65262306a36Sopenharmony_ci if (nr_timedout) 65362306a36Sopenharmony_ci __ata_port_freeze(ap); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci /* initialize eh_tries */ 65662306a36Sopenharmony_ci ap->eh_tries = ATA_EH_MAX_TRIES; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 65962306a36Sopenharmony_ci} 66062306a36Sopenharmony_ciEXPORT_SYMBOL(ata_scsi_cmd_error_handler); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci/** 66362306a36Sopenharmony_ci * ata_scsi_port_error_handler - recover the port after the commands 66462306a36Sopenharmony_ci * @host: SCSI host containing the port 66562306a36Sopenharmony_ci * @ap: the ATA port 66662306a36Sopenharmony_ci * 66762306a36Sopenharmony_ci * Handle the recovery of the port @ap after all the commands 66862306a36Sopenharmony_ci * have been recovered. 66962306a36Sopenharmony_ci */ 67062306a36Sopenharmony_civoid ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) 67162306a36Sopenharmony_ci{ 67262306a36Sopenharmony_ci unsigned long flags; 67362306a36Sopenharmony_ci struct ata_link *link; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci /* acquire EH ownership */ 67662306a36Sopenharmony_ci ata_eh_acquire(ap); 67762306a36Sopenharmony_ci repeat: 67862306a36Sopenharmony_ci /* kill fast drain timer */ 67962306a36Sopenharmony_ci del_timer_sync(&ap->fastdrain_timer); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci /* process port resume request */ 68262306a36Sopenharmony_ci ata_eh_handle_port_resume(ap); 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci /* fetch & clear EH info */ 68562306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci ata_for_each_link(link, ap, HOST_FIRST) { 68862306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 68962306a36Sopenharmony_ci struct ata_device *dev; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci memset(&link->eh_context, 0, sizeof(link->eh_context)); 69262306a36Sopenharmony_ci link->eh_context.i = link->eh_info; 69362306a36Sopenharmony_ci memset(&link->eh_info, 0, sizeof(link->eh_info)); 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 69662306a36Sopenharmony_ci int devno = dev->devno; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci ehc->saved_xfer_mode[devno] = dev->xfer_mode; 69962306a36Sopenharmony_ci if (ata_ncq_enabled(dev)) 70062306a36Sopenharmony_ci ehc->saved_ncq_enabled |= 1 << devno; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci /* If we are resuming, wake up the device */ 70362306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_RESUMING) 70462306a36Sopenharmony_ci ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; 70962306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_EH_PENDING; 71062306a36Sopenharmony_ci ap->excl_link = NULL; /* don't maintain exclusion over EH */ 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci /* invoke EH, skip if unloading or suspended */ 71562306a36Sopenharmony_ci if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED))) 71662306a36Sopenharmony_ci ap->ops->error_handler(ap); 71762306a36Sopenharmony_ci else { 71862306a36Sopenharmony_ci /* if unloading, commence suicide */ 71962306a36Sopenharmony_ci if ((ap->pflags & ATA_PFLAG_UNLOADING) && 72062306a36Sopenharmony_ci !(ap->pflags & ATA_PFLAG_UNLOADED)) 72162306a36Sopenharmony_ci ata_eh_unload(ap); 72262306a36Sopenharmony_ci ata_eh_finish(ap); 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci /* process port suspend request */ 72662306a36Sopenharmony_ci ata_eh_handle_port_suspend(ap); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci /* 72962306a36Sopenharmony_ci * Exception might have happened after ->error_handler recovered the 73062306a36Sopenharmony_ci * port but before this point. Repeat EH in such case. 73162306a36Sopenharmony_ci */ 73262306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_EH_PENDING) { 73562306a36Sopenharmony_ci if (--ap->eh_tries) { 73662306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 73762306a36Sopenharmony_ci goto repeat; 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci ata_port_err(ap, 74062306a36Sopenharmony_ci "EH pending after %d tries, giving up\n", 74162306a36Sopenharmony_ci ATA_EH_MAX_TRIES); 74262306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_EH_PENDING; 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci /* this run is complete, make sure EH info is clear */ 74662306a36Sopenharmony_ci ata_for_each_link(link, ap, HOST_FIRST) 74762306a36Sopenharmony_ci memset(&link->eh_info, 0, sizeof(link->eh_info)); 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci /* 75062306a36Sopenharmony_ci * end eh (clear host_eh_scheduled) while holding ap->lock such that if 75162306a36Sopenharmony_ci * exception occurs after this point but before EH completion, SCSI 75262306a36Sopenharmony_ci * midlayer will re-initiate EH. 75362306a36Sopenharmony_ci */ 75462306a36Sopenharmony_ci ap->ops->end_eh(ap); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 75762306a36Sopenharmony_ci ata_eh_release(ap); 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci scsi_eh_flush_done_q(&ap->eh_done_q); 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci /* clean up */ 76262306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_RESUMING; 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_LOADING) 76762306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_LOADING; 76862306a36Sopenharmony_ci else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && 76962306a36Sopenharmony_ci !(ap->flags & ATA_FLAG_SAS_HOST)) 77062306a36Sopenharmony_ci schedule_delayed_work(&ap->hotplug_task, 0); 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_RECOVERED) 77362306a36Sopenharmony_ci ata_port_info(ap, "EH complete\n"); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci ap->pflags &= ~(ATA_PFLAG_SCSI_HOTPLUG | ATA_PFLAG_RECOVERED); 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci /* tell wait_eh that we're done */ 77862306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_EH_IN_PROGRESS; 77962306a36Sopenharmony_ci wake_up_all(&ap->eh_wait_q); 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 78262306a36Sopenharmony_ci} 78362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_port_error_handler); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci/** 78662306a36Sopenharmony_ci * ata_port_wait_eh - Wait for the currently pending EH to complete 78762306a36Sopenharmony_ci * @ap: Port to wait EH for 78862306a36Sopenharmony_ci * 78962306a36Sopenharmony_ci * Wait until the currently pending EH is complete. 79062306a36Sopenharmony_ci * 79162306a36Sopenharmony_ci * LOCKING: 79262306a36Sopenharmony_ci * Kernel thread context (may sleep). 79362306a36Sopenharmony_ci */ 79462306a36Sopenharmony_civoid ata_port_wait_eh(struct ata_port *ap) 79562306a36Sopenharmony_ci{ 79662306a36Sopenharmony_ci unsigned long flags; 79762306a36Sopenharmony_ci DEFINE_WAIT(wait); 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci retry: 80062306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci while (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) { 80362306a36Sopenharmony_ci prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE); 80462306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 80562306a36Sopenharmony_ci schedule(); 80662306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 80762306a36Sopenharmony_ci } 80862306a36Sopenharmony_ci finish_wait(&ap->eh_wait_q, &wait); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci /* make sure SCSI EH is complete */ 81362306a36Sopenharmony_ci if (scsi_host_in_recovery(ap->scsi_host)) { 81462306a36Sopenharmony_ci ata_msleep(ap, 10); 81562306a36Sopenharmony_ci goto retry; 81662306a36Sopenharmony_ci } 81762306a36Sopenharmony_ci} 81862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_wait_eh); 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_cistatic unsigned int ata_eh_nr_in_flight(struct ata_port *ap) 82162306a36Sopenharmony_ci{ 82262306a36Sopenharmony_ci struct ata_queued_cmd *qc; 82362306a36Sopenharmony_ci unsigned int tag; 82462306a36Sopenharmony_ci unsigned int nr = 0; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci /* count only non-internal commands */ 82762306a36Sopenharmony_ci ata_qc_for_each(ap, qc, tag) { 82862306a36Sopenharmony_ci if (qc) 82962306a36Sopenharmony_ci nr++; 83062306a36Sopenharmony_ci } 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci return nr; 83362306a36Sopenharmony_ci} 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_civoid ata_eh_fastdrain_timerfn(struct timer_list *t) 83662306a36Sopenharmony_ci{ 83762306a36Sopenharmony_ci struct ata_port *ap = from_timer(ap, t, fastdrain_timer); 83862306a36Sopenharmony_ci unsigned long flags; 83962306a36Sopenharmony_ci unsigned int cnt; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci cnt = ata_eh_nr_in_flight(ap); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci /* are we done? */ 84662306a36Sopenharmony_ci if (!cnt) 84762306a36Sopenharmony_ci goto out_unlock; 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci if (cnt == ap->fastdrain_cnt) { 85062306a36Sopenharmony_ci struct ata_queued_cmd *qc; 85162306a36Sopenharmony_ci unsigned int tag; 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci /* No progress during the last interval, tag all 85462306a36Sopenharmony_ci * in-flight qcs as timed out and freeze the port. 85562306a36Sopenharmony_ci */ 85662306a36Sopenharmony_ci ata_qc_for_each(ap, qc, tag) { 85762306a36Sopenharmony_ci if (qc) 85862306a36Sopenharmony_ci qc->err_mask |= AC_ERR_TIMEOUT; 85962306a36Sopenharmony_ci } 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci ata_port_freeze(ap); 86262306a36Sopenharmony_ci } else { 86362306a36Sopenharmony_ci /* some qcs have finished, give it another chance */ 86462306a36Sopenharmony_ci ap->fastdrain_cnt = cnt; 86562306a36Sopenharmony_ci ap->fastdrain_timer.expires = 86662306a36Sopenharmony_ci ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL); 86762306a36Sopenharmony_ci add_timer(&ap->fastdrain_timer); 86862306a36Sopenharmony_ci } 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci out_unlock: 87162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 87262306a36Sopenharmony_ci} 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci/** 87562306a36Sopenharmony_ci * ata_eh_set_pending - set ATA_PFLAG_EH_PENDING and activate fast drain 87662306a36Sopenharmony_ci * @ap: target ATA port 87762306a36Sopenharmony_ci * @fastdrain: activate fast drain 87862306a36Sopenharmony_ci * 87962306a36Sopenharmony_ci * Set ATA_PFLAG_EH_PENDING and activate fast drain if @fastdrain 88062306a36Sopenharmony_ci * is non-zero and EH wasn't pending before. Fast drain ensures 88162306a36Sopenharmony_ci * that EH kicks in in timely manner. 88262306a36Sopenharmony_ci * 88362306a36Sopenharmony_ci * LOCKING: 88462306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 88562306a36Sopenharmony_ci */ 88662306a36Sopenharmony_cistatic void ata_eh_set_pending(struct ata_port *ap, int fastdrain) 88762306a36Sopenharmony_ci{ 88862306a36Sopenharmony_ci unsigned int cnt; 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci /* already scheduled? */ 89162306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_EH_PENDING) 89262306a36Sopenharmony_ci return; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_EH_PENDING; 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci if (!fastdrain) 89762306a36Sopenharmony_ci return; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci /* do we have in-flight qcs? */ 90062306a36Sopenharmony_ci cnt = ata_eh_nr_in_flight(ap); 90162306a36Sopenharmony_ci if (!cnt) 90262306a36Sopenharmony_ci return; 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci /* activate fast drain */ 90562306a36Sopenharmony_ci ap->fastdrain_cnt = cnt; 90662306a36Sopenharmony_ci ap->fastdrain_timer.expires = 90762306a36Sopenharmony_ci ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL); 90862306a36Sopenharmony_ci add_timer(&ap->fastdrain_timer); 90962306a36Sopenharmony_ci} 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci/** 91262306a36Sopenharmony_ci * ata_qc_schedule_eh - schedule qc for error handling 91362306a36Sopenharmony_ci * @qc: command to schedule error handling for 91462306a36Sopenharmony_ci * 91562306a36Sopenharmony_ci * Schedule error handling for @qc. EH will kick in as soon as 91662306a36Sopenharmony_ci * other commands are drained. 91762306a36Sopenharmony_ci * 91862306a36Sopenharmony_ci * LOCKING: 91962306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 92062306a36Sopenharmony_ci */ 92162306a36Sopenharmony_civoid ata_qc_schedule_eh(struct ata_queued_cmd *qc) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci struct ata_port *ap = qc->ap; 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_EH; 92662306a36Sopenharmony_ci ata_eh_set_pending(ap, 1); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci /* The following will fail if timeout has already expired. 92962306a36Sopenharmony_ci * ata_scsi_error() takes care of such scmds on EH entry. 93062306a36Sopenharmony_ci * Note that ATA_QCFLAG_EH is unconditionally set after 93162306a36Sopenharmony_ci * this function completes. 93262306a36Sopenharmony_ci */ 93362306a36Sopenharmony_ci blk_abort_request(scsi_cmd_to_rq(qc->scsicmd)); 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci/** 93762306a36Sopenharmony_ci * ata_std_sched_eh - non-libsas ata_ports issue eh with this common routine 93862306a36Sopenharmony_ci * @ap: ATA port to schedule EH for 93962306a36Sopenharmony_ci * 94062306a36Sopenharmony_ci * LOCKING: inherited from ata_port_schedule_eh 94162306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 94262306a36Sopenharmony_ci */ 94362306a36Sopenharmony_civoid ata_std_sched_eh(struct ata_port *ap) 94462306a36Sopenharmony_ci{ 94562306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_INITIALIZING) 94662306a36Sopenharmony_ci return; 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci ata_eh_set_pending(ap, 1); 94962306a36Sopenharmony_ci scsi_schedule_eh(ap->scsi_host); 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci trace_ata_std_sched_eh(ap); 95262306a36Sopenharmony_ci} 95362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_std_sched_eh); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci/** 95662306a36Sopenharmony_ci * ata_std_end_eh - non-libsas ata_ports complete eh with this common routine 95762306a36Sopenharmony_ci * @ap: ATA port to end EH for 95862306a36Sopenharmony_ci * 95962306a36Sopenharmony_ci * In the libata object model there is a 1:1 mapping of ata_port to 96062306a36Sopenharmony_ci * shost, so host fields can be directly manipulated under ap->lock, in 96162306a36Sopenharmony_ci * the libsas case we need to hold a lock at the ha->level to coordinate 96262306a36Sopenharmony_ci * these events. 96362306a36Sopenharmony_ci * 96462306a36Sopenharmony_ci * LOCKING: 96562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 96662306a36Sopenharmony_ci */ 96762306a36Sopenharmony_civoid ata_std_end_eh(struct ata_port *ap) 96862306a36Sopenharmony_ci{ 96962306a36Sopenharmony_ci struct Scsi_Host *host = ap->scsi_host; 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci host->host_eh_scheduled = 0; 97262306a36Sopenharmony_ci} 97362306a36Sopenharmony_ciEXPORT_SYMBOL(ata_std_end_eh); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci/** 97762306a36Sopenharmony_ci * ata_port_schedule_eh - schedule error handling without a qc 97862306a36Sopenharmony_ci * @ap: ATA port to schedule EH for 97962306a36Sopenharmony_ci * 98062306a36Sopenharmony_ci * Schedule error handling for @ap. EH will kick in as soon as 98162306a36Sopenharmony_ci * all commands are drained. 98262306a36Sopenharmony_ci * 98362306a36Sopenharmony_ci * LOCKING: 98462306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 98562306a36Sopenharmony_ci */ 98662306a36Sopenharmony_civoid ata_port_schedule_eh(struct ata_port *ap) 98762306a36Sopenharmony_ci{ 98862306a36Sopenharmony_ci /* see: ata_std_sched_eh, unless you know better */ 98962306a36Sopenharmony_ci ap->ops->sched_eh(ap); 99062306a36Sopenharmony_ci} 99162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_schedule_eh); 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_cistatic int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) 99462306a36Sopenharmony_ci{ 99562306a36Sopenharmony_ci struct ata_queued_cmd *qc; 99662306a36Sopenharmony_ci int tag, nr_aborted = 0; 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci /* we're gonna abort all commands, no need for fast drain */ 99962306a36Sopenharmony_ci ata_eh_set_pending(ap, 0); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci /* include internal tag in iteration */ 100262306a36Sopenharmony_ci ata_qc_for_each_with_internal(ap, qc, tag) { 100362306a36Sopenharmony_ci if (qc && (!link || qc->dev->link == link)) { 100462306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_EH; 100562306a36Sopenharmony_ci ata_qc_complete(qc); 100662306a36Sopenharmony_ci nr_aborted++; 100762306a36Sopenharmony_ci } 100862306a36Sopenharmony_ci } 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci if (!nr_aborted) 101162306a36Sopenharmony_ci ata_port_schedule_eh(ap); 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci return nr_aborted; 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci/** 101762306a36Sopenharmony_ci * ata_link_abort - abort all qc's on the link 101862306a36Sopenharmony_ci * @link: ATA link to abort qc's for 101962306a36Sopenharmony_ci * 102062306a36Sopenharmony_ci * Abort all active qc's active on @link and schedule EH. 102162306a36Sopenharmony_ci * 102262306a36Sopenharmony_ci * LOCKING: 102362306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 102462306a36Sopenharmony_ci * 102562306a36Sopenharmony_ci * RETURNS: 102662306a36Sopenharmony_ci * Number of aborted qc's. 102762306a36Sopenharmony_ci */ 102862306a36Sopenharmony_ciint ata_link_abort(struct ata_link *link) 102962306a36Sopenharmony_ci{ 103062306a36Sopenharmony_ci return ata_do_link_abort(link->ap, link); 103162306a36Sopenharmony_ci} 103262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_link_abort); 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci/** 103562306a36Sopenharmony_ci * ata_port_abort - abort all qc's on the port 103662306a36Sopenharmony_ci * @ap: ATA port to abort qc's for 103762306a36Sopenharmony_ci * 103862306a36Sopenharmony_ci * Abort all active qc's of @ap and schedule EH. 103962306a36Sopenharmony_ci * 104062306a36Sopenharmony_ci * LOCKING: 104162306a36Sopenharmony_ci * spin_lock_irqsave(host_set lock) 104262306a36Sopenharmony_ci * 104362306a36Sopenharmony_ci * RETURNS: 104462306a36Sopenharmony_ci * Number of aborted qc's. 104562306a36Sopenharmony_ci */ 104662306a36Sopenharmony_ciint ata_port_abort(struct ata_port *ap) 104762306a36Sopenharmony_ci{ 104862306a36Sopenharmony_ci return ata_do_link_abort(ap, NULL); 104962306a36Sopenharmony_ci} 105062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_abort); 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci/** 105362306a36Sopenharmony_ci * __ata_port_freeze - freeze port 105462306a36Sopenharmony_ci * @ap: ATA port to freeze 105562306a36Sopenharmony_ci * 105662306a36Sopenharmony_ci * This function is called when HSM violation or some other 105762306a36Sopenharmony_ci * condition disrupts normal operation of the port. Frozen port 105862306a36Sopenharmony_ci * is not allowed to perform any operation until the port is 105962306a36Sopenharmony_ci * thawed, which usually follows a successful reset. 106062306a36Sopenharmony_ci * 106162306a36Sopenharmony_ci * ap->ops->freeze() callback can be used for freezing the port 106262306a36Sopenharmony_ci * hardware-wise (e.g. mask interrupt and stop DMA engine). If a 106362306a36Sopenharmony_ci * port cannot be frozen hardware-wise, the interrupt handler 106462306a36Sopenharmony_ci * must ack and clear interrupts unconditionally while the port 106562306a36Sopenharmony_ci * is frozen. 106662306a36Sopenharmony_ci * 106762306a36Sopenharmony_ci * LOCKING: 106862306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 106962306a36Sopenharmony_ci */ 107062306a36Sopenharmony_cistatic void __ata_port_freeze(struct ata_port *ap) 107162306a36Sopenharmony_ci{ 107262306a36Sopenharmony_ci if (ap->ops->freeze) 107362306a36Sopenharmony_ci ap->ops->freeze(ap); 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_FROZEN; 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_ci trace_ata_port_freeze(ap); 107862306a36Sopenharmony_ci} 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci/** 108162306a36Sopenharmony_ci * ata_port_freeze - abort & freeze port 108262306a36Sopenharmony_ci * @ap: ATA port to freeze 108362306a36Sopenharmony_ci * 108462306a36Sopenharmony_ci * Abort and freeze @ap. The freeze operation must be called 108562306a36Sopenharmony_ci * first, because some hardware requires special operations 108662306a36Sopenharmony_ci * before the taskfile registers are accessible. 108762306a36Sopenharmony_ci * 108862306a36Sopenharmony_ci * LOCKING: 108962306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 109062306a36Sopenharmony_ci * 109162306a36Sopenharmony_ci * RETURNS: 109262306a36Sopenharmony_ci * Number of aborted commands. 109362306a36Sopenharmony_ci */ 109462306a36Sopenharmony_ciint ata_port_freeze(struct ata_port *ap) 109562306a36Sopenharmony_ci{ 109662306a36Sopenharmony_ci __ata_port_freeze(ap); 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci return ata_port_abort(ap); 109962306a36Sopenharmony_ci} 110062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_port_freeze); 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci/** 110362306a36Sopenharmony_ci * ata_eh_freeze_port - EH helper to freeze port 110462306a36Sopenharmony_ci * @ap: ATA port to freeze 110562306a36Sopenharmony_ci * 110662306a36Sopenharmony_ci * Freeze @ap. 110762306a36Sopenharmony_ci * 110862306a36Sopenharmony_ci * LOCKING: 110962306a36Sopenharmony_ci * None. 111062306a36Sopenharmony_ci */ 111162306a36Sopenharmony_civoid ata_eh_freeze_port(struct ata_port *ap) 111262306a36Sopenharmony_ci{ 111362306a36Sopenharmony_ci unsigned long flags; 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 111662306a36Sopenharmony_ci __ata_port_freeze(ap); 111762306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 111862306a36Sopenharmony_ci} 111962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_eh_freeze_port); 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci/** 112262306a36Sopenharmony_ci * ata_eh_thaw_port - EH helper to thaw port 112362306a36Sopenharmony_ci * @ap: ATA port to thaw 112462306a36Sopenharmony_ci * 112562306a36Sopenharmony_ci * Thaw frozen port @ap. 112662306a36Sopenharmony_ci * 112762306a36Sopenharmony_ci * LOCKING: 112862306a36Sopenharmony_ci * None. 112962306a36Sopenharmony_ci */ 113062306a36Sopenharmony_civoid ata_eh_thaw_port(struct ata_port *ap) 113162306a36Sopenharmony_ci{ 113262306a36Sopenharmony_ci unsigned long flags; 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_FROZEN; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci if (ap->ops->thaw) 113962306a36Sopenharmony_ci ap->ops->thaw(ap); 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci trace_ata_port_thaw(ap); 114462306a36Sopenharmony_ci} 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_cistatic void ata_eh_scsidone(struct scsi_cmnd *scmd) 114762306a36Sopenharmony_ci{ 114862306a36Sopenharmony_ci /* nada */ 114962306a36Sopenharmony_ci} 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_cistatic void __ata_eh_qc_complete(struct ata_queued_cmd *qc) 115262306a36Sopenharmony_ci{ 115362306a36Sopenharmony_ci struct ata_port *ap = qc->ap; 115462306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 115562306a36Sopenharmony_ci unsigned long flags; 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 115862306a36Sopenharmony_ci qc->scsidone = ata_eh_scsidone; 115962306a36Sopenharmony_ci __ata_qc_complete(qc); 116062306a36Sopenharmony_ci WARN_ON(ata_tag_valid(qc->tag)); 116162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci scsi_eh_finish_cmd(scmd, &ap->eh_done_q); 116462306a36Sopenharmony_ci} 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci/** 116762306a36Sopenharmony_ci * ata_eh_qc_complete - Complete an active ATA command from EH 116862306a36Sopenharmony_ci * @qc: Command to complete 116962306a36Sopenharmony_ci * 117062306a36Sopenharmony_ci * Indicate to the mid and upper layers that an ATA command has 117162306a36Sopenharmony_ci * completed. To be used from EH. 117262306a36Sopenharmony_ci */ 117362306a36Sopenharmony_civoid ata_eh_qc_complete(struct ata_queued_cmd *qc) 117462306a36Sopenharmony_ci{ 117562306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 117662306a36Sopenharmony_ci scmd->retries = scmd->allowed; 117762306a36Sopenharmony_ci __ata_eh_qc_complete(qc); 117862306a36Sopenharmony_ci} 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci/** 118162306a36Sopenharmony_ci * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH 118262306a36Sopenharmony_ci * @qc: Command to retry 118362306a36Sopenharmony_ci * 118462306a36Sopenharmony_ci * Indicate to the mid and upper layers that an ATA command 118562306a36Sopenharmony_ci * should be retried. To be used from EH. 118662306a36Sopenharmony_ci * 118762306a36Sopenharmony_ci * SCSI midlayer limits the number of retries to scmd->allowed. 118862306a36Sopenharmony_ci * scmd->allowed is incremented for commands which get retried 118962306a36Sopenharmony_ci * due to unrelated failures (qc->err_mask is zero). 119062306a36Sopenharmony_ci */ 119162306a36Sopenharmony_civoid ata_eh_qc_retry(struct ata_queued_cmd *qc) 119262306a36Sopenharmony_ci{ 119362306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 119462306a36Sopenharmony_ci if (!qc->err_mask) 119562306a36Sopenharmony_ci scmd->allowed++; 119662306a36Sopenharmony_ci __ata_eh_qc_complete(qc); 119762306a36Sopenharmony_ci} 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_ci/** 120062306a36Sopenharmony_ci * ata_dev_disable - disable ATA device 120162306a36Sopenharmony_ci * @dev: ATA device to disable 120262306a36Sopenharmony_ci * 120362306a36Sopenharmony_ci * Disable @dev. 120462306a36Sopenharmony_ci * 120562306a36Sopenharmony_ci * Locking: 120662306a36Sopenharmony_ci * EH context. 120762306a36Sopenharmony_ci */ 120862306a36Sopenharmony_civoid ata_dev_disable(struct ata_device *dev) 120962306a36Sopenharmony_ci{ 121062306a36Sopenharmony_ci if (!ata_dev_enabled(dev)) 121162306a36Sopenharmony_ci return; 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci ata_dev_warn(dev, "disable device\n"); 121462306a36Sopenharmony_ci ata_acpi_on_disable(dev); 121562306a36Sopenharmony_ci ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); 121662306a36Sopenharmony_ci dev->class++; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci /* From now till the next successful probe, ering is used to 121962306a36Sopenharmony_ci * track probe failures. Clear accumulated device error info. 122062306a36Sopenharmony_ci */ 122162306a36Sopenharmony_ci ata_ering_clear(&dev->ering); 122262306a36Sopenharmony_ci} 122362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_dev_disable); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci/** 122662306a36Sopenharmony_ci * ata_eh_detach_dev - detach ATA device 122762306a36Sopenharmony_ci * @dev: ATA device to detach 122862306a36Sopenharmony_ci * 122962306a36Sopenharmony_ci * Detach @dev. 123062306a36Sopenharmony_ci * 123162306a36Sopenharmony_ci * LOCKING: 123262306a36Sopenharmony_ci * None. 123362306a36Sopenharmony_ci */ 123462306a36Sopenharmony_civoid ata_eh_detach_dev(struct ata_device *dev) 123562306a36Sopenharmony_ci{ 123662306a36Sopenharmony_ci struct ata_link *link = dev->link; 123762306a36Sopenharmony_ci struct ata_port *ap = link->ap; 123862306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 123962306a36Sopenharmony_ci unsigned long flags; 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci /* 124262306a36Sopenharmony_ci * If the device is still enabled, transition it to standby power mode 124362306a36Sopenharmony_ci * (i.e. spin down HDDs). 124462306a36Sopenharmony_ci */ 124562306a36Sopenharmony_ci if (ata_dev_enabled(dev)) 124662306a36Sopenharmony_ci ata_dev_power_set_standby(dev); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci ata_dev_disable(dev); 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_DETACH; 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci if (ata_scsi_offline_dev(dev)) { 125562306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_DETACHED; 125662306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; 125762306a36Sopenharmony_ci } 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci /* clear per-dev EH info */ 126062306a36Sopenharmony_ci ata_eh_clear_action(link, dev, &link->eh_info, ATA_EH_PERDEV_MASK); 126162306a36Sopenharmony_ci ata_eh_clear_action(link, dev, &link->eh_context.i, ATA_EH_PERDEV_MASK); 126262306a36Sopenharmony_ci ehc->saved_xfer_mode[dev->devno] = 0; 126362306a36Sopenharmony_ci ehc->saved_ncq_enabled &= ~(1 << dev->devno); 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 126662306a36Sopenharmony_ci} 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci/** 126962306a36Sopenharmony_ci * ata_eh_about_to_do - about to perform eh_action 127062306a36Sopenharmony_ci * @link: target ATA link 127162306a36Sopenharmony_ci * @dev: target ATA dev for per-dev action (can be NULL) 127262306a36Sopenharmony_ci * @action: action about to be performed 127362306a36Sopenharmony_ci * 127462306a36Sopenharmony_ci * Called just before performing EH actions to clear related bits 127562306a36Sopenharmony_ci * in @link->eh_info such that eh actions are not unnecessarily 127662306a36Sopenharmony_ci * repeated. 127762306a36Sopenharmony_ci * 127862306a36Sopenharmony_ci * LOCKING: 127962306a36Sopenharmony_ci * None. 128062306a36Sopenharmony_ci */ 128162306a36Sopenharmony_civoid ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, 128262306a36Sopenharmony_ci unsigned int action) 128362306a36Sopenharmony_ci{ 128462306a36Sopenharmony_ci struct ata_port *ap = link->ap; 128562306a36Sopenharmony_ci struct ata_eh_info *ehi = &link->eh_info; 128662306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 128762306a36Sopenharmony_ci unsigned long flags; 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci trace_ata_eh_about_to_do(link, dev ? dev->devno : 0, action); 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci ata_eh_clear_action(link, dev, ehi, action); 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci /* About to take EH action, set RECOVERED. Ignore actions on 129662306a36Sopenharmony_ci * slave links as master will do them again. 129762306a36Sopenharmony_ci */ 129862306a36Sopenharmony_ci if (!(ehc->i.flags & ATA_EHI_QUIET) && link != ap->slave_link) 129962306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_RECOVERED; 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 130262306a36Sopenharmony_ci} 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci/** 130562306a36Sopenharmony_ci * ata_eh_done - EH action complete 130662306a36Sopenharmony_ci * @link: ATA link for which EH actions are complete 130762306a36Sopenharmony_ci * @dev: target ATA dev for per-dev action (can be NULL) 130862306a36Sopenharmony_ci * @action: action just completed 130962306a36Sopenharmony_ci * 131062306a36Sopenharmony_ci * Called right after performing EH actions to clear related bits 131162306a36Sopenharmony_ci * in @link->eh_context. 131262306a36Sopenharmony_ci * 131362306a36Sopenharmony_ci * LOCKING: 131462306a36Sopenharmony_ci * None. 131562306a36Sopenharmony_ci */ 131662306a36Sopenharmony_civoid ata_eh_done(struct ata_link *link, struct ata_device *dev, 131762306a36Sopenharmony_ci unsigned int action) 131862306a36Sopenharmony_ci{ 131962306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci trace_ata_eh_done(link, dev ? dev->devno : 0, action); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci ata_eh_clear_action(link, dev, &ehc->i, action); 132462306a36Sopenharmony_ci} 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci/** 132762306a36Sopenharmony_ci * ata_err_string - convert err_mask to descriptive string 132862306a36Sopenharmony_ci * @err_mask: error mask to convert to string 132962306a36Sopenharmony_ci * 133062306a36Sopenharmony_ci * Convert @err_mask to descriptive string. Errors are 133162306a36Sopenharmony_ci * prioritized according to severity and only the most severe 133262306a36Sopenharmony_ci * error is reported. 133362306a36Sopenharmony_ci * 133462306a36Sopenharmony_ci * LOCKING: 133562306a36Sopenharmony_ci * None. 133662306a36Sopenharmony_ci * 133762306a36Sopenharmony_ci * RETURNS: 133862306a36Sopenharmony_ci * Descriptive string for @err_mask 133962306a36Sopenharmony_ci */ 134062306a36Sopenharmony_cistatic const char *ata_err_string(unsigned int err_mask) 134162306a36Sopenharmony_ci{ 134262306a36Sopenharmony_ci if (err_mask & AC_ERR_HOST_BUS) 134362306a36Sopenharmony_ci return "host bus error"; 134462306a36Sopenharmony_ci if (err_mask & AC_ERR_ATA_BUS) 134562306a36Sopenharmony_ci return "ATA bus error"; 134662306a36Sopenharmony_ci if (err_mask & AC_ERR_TIMEOUT) 134762306a36Sopenharmony_ci return "timeout"; 134862306a36Sopenharmony_ci if (err_mask & AC_ERR_HSM) 134962306a36Sopenharmony_ci return "HSM violation"; 135062306a36Sopenharmony_ci if (err_mask & AC_ERR_SYSTEM) 135162306a36Sopenharmony_ci return "internal error"; 135262306a36Sopenharmony_ci if (err_mask & AC_ERR_MEDIA) 135362306a36Sopenharmony_ci return "media error"; 135462306a36Sopenharmony_ci if (err_mask & AC_ERR_INVALID) 135562306a36Sopenharmony_ci return "invalid argument"; 135662306a36Sopenharmony_ci if (err_mask & AC_ERR_DEV) 135762306a36Sopenharmony_ci return "device error"; 135862306a36Sopenharmony_ci if (err_mask & AC_ERR_NCQ) 135962306a36Sopenharmony_ci return "NCQ error"; 136062306a36Sopenharmony_ci if (err_mask & AC_ERR_NODEV_HINT) 136162306a36Sopenharmony_ci return "Polling detection error"; 136262306a36Sopenharmony_ci return "unknown error"; 136362306a36Sopenharmony_ci} 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ci/** 136662306a36Sopenharmony_ci * atapi_eh_tur - perform ATAPI TEST_UNIT_READY 136762306a36Sopenharmony_ci * @dev: target ATAPI device 136862306a36Sopenharmony_ci * @r_sense_key: out parameter for sense_key 136962306a36Sopenharmony_ci * 137062306a36Sopenharmony_ci * Perform ATAPI TEST_UNIT_READY. 137162306a36Sopenharmony_ci * 137262306a36Sopenharmony_ci * LOCKING: 137362306a36Sopenharmony_ci * EH context (may sleep). 137462306a36Sopenharmony_ci * 137562306a36Sopenharmony_ci * RETURNS: 137662306a36Sopenharmony_ci * 0 on success, AC_ERR_* mask on failure. 137762306a36Sopenharmony_ci */ 137862306a36Sopenharmony_ciunsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) 137962306a36Sopenharmony_ci{ 138062306a36Sopenharmony_ci u8 cdb[ATAPI_CDB_LEN] = { TEST_UNIT_READY, 0, 0, 0, 0, 0 }; 138162306a36Sopenharmony_ci struct ata_taskfile tf; 138262306a36Sopenharmony_ci unsigned int err_mask; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci ata_tf_init(dev, &tf); 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 138762306a36Sopenharmony_ci tf.command = ATA_CMD_PACKET; 138862306a36Sopenharmony_ci tf.protocol = ATAPI_PROT_NODATA; 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0); 139162306a36Sopenharmony_ci if (err_mask == AC_ERR_DEV) 139262306a36Sopenharmony_ci *r_sense_key = tf.error >> 4; 139362306a36Sopenharmony_ci return err_mask; 139462306a36Sopenharmony_ci} 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci/** 139762306a36Sopenharmony_ci * ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT 139862306a36Sopenharmony_ci * @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to 139962306a36Sopenharmony_ci * 140062306a36Sopenharmony_ci * Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK 140162306a36Sopenharmony_ci * SENSE. This function is an EH helper. 140262306a36Sopenharmony_ci * 140362306a36Sopenharmony_ci * LOCKING: 140462306a36Sopenharmony_ci * Kernel thread context (may sleep). 140562306a36Sopenharmony_ci * 140662306a36Sopenharmony_ci * RETURNS: 140762306a36Sopenharmony_ci * true if sense data could be fetched, false otherwise. 140862306a36Sopenharmony_ci */ 140962306a36Sopenharmony_cistatic bool ata_eh_request_sense(struct ata_queued_cmd *qc) 141062306a36Sopenharmony_ci{ 141162306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 141262306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 141362306a36Sopenharmony_ci struct ata_taskfile tf; 141462306a36Sopenharmony_ci unsigned int err_mask; 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci if (ata_port_is_frozen(qc->ap)) { 141762306a36Sopenharmony_ci ata_dev_warn(dev, "sense data available but port frozen\n"); 141862306a36Sopenharmony_ci return false; 141962306a36Sopenharmony_ci } 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci if (!ata_id_sense_reporting_enabled(dev->id)) { 142262306a36Sopenharmony_ci ata_dev_warn(qc->dev, "sense data reporting disabled\n"); 142362306a36Sopenharmony_ci return false; 142462306a36Sopenharmony_ci } 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci ata_tf_init(dev, &tf); 142762306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 142862306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48; 142962306a36Sopenharmony_ci tf.command = ATA_CMD_REQ_SENSE_DATA; 143062306a36Sopenharmony_ci tf.protocol = ATA_PROT_NODATA; 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); 143362306a36Sopenharmony_ci /* Ignore err_mask; ATA_ERR might be set */ 143462306a36Sopenharmony_ci if (tf.status & ATA_SENSE) { 143562306a36Sopenharmony_ci if (ata_scsi_sense_is_valid(tf.lbah, tf.lbam, tf.lbal)) { 143662306a36Sopenharmony_ci /* Set sense without also setting scsicmd->result */ 143762306a36Sopenharmony_ci scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, 143862306a36Sopenharmony_ci cmd->sense_buffer, tf.lbah, 143962306a36Sopenharmony_ci tf.lbam, tf.lbal); 144062306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_SENSE_VALID; 144162306a36Sopenharmony_ci return true; 144262306a36Sopenharmony_ci } 144362306a36Sopenharmony_ci } else { 144462306a36Sopenharmony_ci ata_dev_warn(dev, "request sense failed stat %02x emask %x\n", 144562306a36Sopenharmony_ci tf.status, err_mask); 144662306a36Sopenharmony_ci } 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci return false; 144962306a36Sopenharmony_ci} 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci/** 145262306a36Sopenharmony_ci * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE 145362306a36Sopenharmony_ci * @dev: device to perform REQUEST_SENSE to 145462306a36Sopenharmony_ci * @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long) 145562306a36Sopenharmony_ci * @dfl_sense_key: default sense key to use 145662306a36Sopenharmony_ci * 145762306a36Sopenharmony_ci * Perform ATAPI REQUEST_SENSE after the device reported CHECK 145862306a36Sopenharmony_ci * SENSE. This function is EH helper. 145962306a36Sopenharmony_ci * 146062306a36Sopenharmony_ci * LOCKING: 146162306a36Sopenharmony_ci * Kernel thread context (may sleep). 146262306a36Sopenharmony_ci * 146362306a36Sopenharmony_ci * RETURNS: 146462306a36Sopenharmony_ci * 0 on success, AC_ERR_* mask on failure 146562306a36Sopenharmony_ci */ 146662306a36Sopenharmony_ciunsigned int atapi_eh_request_sense(struct ata_device *dev, 146762306a36Sopenharmony_ci u8 *sense_buf, u8 dfl_sense_key) 146862306a36Sopenharmony_ci{ 146962306a36Sopenharmony_ci u8 cdb[ATAPI_CDB_LEN] = 147062306a36Sopenharmony_ci { REQUEST_SENSE, 0, 0, 0, SCSI_SENSE_BUFFERSIZE, 0 }; 147162306a36Sopenharmony_ci struct ata_port *ap = dev->link->ap; 147262306a36Sopenharmony_ci struct ata_taskfile tf; 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci /* initialize sense_buf with the error register, 147762306a36Sopenharmony_ci * for the case where they are -not- overwritten 147862306a36Sopenharmony_ci */ 147962306a36Sopenharmony_ci sense_buf[0] = 0x70; 148062306a36Sopenharmony_ci sense_buf[2] = dfl_sense_key; 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci /* some devices time out if garbage left in tf */ 148362306a36Sopenharmony_ci ata_tf_init(dev, &tf); 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 148662306a36Sopenharmony_ci tf.command = ATA_CMD_PACKET; 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci /* is it pointless to prefer PIO for "safety reasons"? */ 148962306a36Sopenharmony_ci if (ap->flags & ATA_FLAG_PIO_DMA) { 149062306a36Sopenharmony_ci tf.protocol = ATAPI_PROT_DMA; 149162306a36Sopenharmony_ci tf.feature |= ATAPI_PKT_DMA; 149262306a36Sopenharmony_ci } else { 149362306a36Sopenharmony_ci tf.protocol = ATAPI_PROT_PIO; 149462306a36Sopenharmony_ci tf.lbam = SCSI_SENSE_BUFFERSIZE; 149562306a36Sopenharmony_ci tf.lbah = 0; 149662306a36Sopenharmony_ci } 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, 149962306a36Sopenharmony_ci sense_buf, SCSI_SENSE_BUFFERSIZE, 0); 150062306a36Sopenharmony_ci} 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci/** 150362306a36Sopenharmony_ci * ata_eh_analyze_serror - analyze SError for a failed port 150462306a36Sopenharmony_ci * @link: ATA link to analyze SError for 150562306a36Sopenharmony_ci * 150662306a36Sopenharmony_ci * Analyze SError if available and further determine cause of 150762306a36Sopenharmony_ci * failure. 150862306a36Sopenharmony_ci * 150962306a36Sopenharmony_ci * LOCKING: 151062306a36Sopenharmony_ci * None. 151162306a36Sopenharmony_ci */ 151262306a36Sopenharmony_cistatic void ata_eh_analyze_serror(struct ata_link *link) 151362306a36Sopenharmony_ci{ 151462306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 151562306a36Sopenharmony_ci u32 serror = ehc->i.serror; 151662306a36Sopenharmony_ci unsigned int err_mask = 0, action = 0; 151762306a36Sopenharmony_ci u32 hotplug_mask; 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci if (serror & (SERR_PERSISTENT | SERR_DATA)) { 152062306a36Sopenharmony_ci err_mask |= AC_ERR_ATA_BUS; 152162306a36Sopenharmony_ci action |= ATA_EH_RESET; 152262306a36Sopenharmony_ci } 152362306a36Sopenharmony_ci if (serror & SERR_PROTOCOL) { 152462306a36Sopenharmony_ci err_mask |= AC_ERR_HSM; 152562306a36Sopenharmony_ci action |= ATA_EH_RESET; 152662306a36Sopenharmony_ci } 152762306a36Sopenharmony_ci if (serror & SERR_INTERNAL) { 152862306a36Sopenharmony_ci err_mask |= AC_ERR_SYSTEM; 152962306a36Sopenharmony_ci action |= ATA_EH_RESET; 153062306a36Sopenharmony_ci } 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci /* Determine whether a hotplug event has occurred. Both 153362306a36Sopenharmony_ci * SError.N/X are considered hotplug events for enabled or 153462306a36Sopenharmony_ci * host links. For disabled PMP links, only N bit is 153562306a36Sopenharmony_ci * considered as X bit is left at 1 for link plugging. 153662306a36Sopenharmony_ci */ 153762306a36Sopenharmony_ci if (link->lpm_policy > ATA_LPM_MAX_POWER) 153862306a36Sopenharmony_ci hotplug_mask = 0; /* hotplug doesn't work w/ LPM */ 153962306a36Sopenharmony_ci else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link)) 154062306a36Sopenharmony_ci hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; 154162306a36Sopenharmony_ci else 154262306a36Sopenharmony_ci hotplug_mask = SERR_PHYRDY_CHG; 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_ci if (serror & hotplug_mask) 154562306a36Sopenharmony_ci ata_ehi_hotplugged(&ehc->i); 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci ehc->i.err_mask |= err_mask; 154862306a36Sopenharmony_ci ehc->i.action |= action; 154962306a36Sopenharmony_ci} 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci/** 155262306a36Sopenharmony_ci * ata_eh_analyze_tf - analyze taskfile of a failed qc 155362306a36Sopenharmony_ci * @qc: qc to analyze 155462306a36Sopenharmony_ci * 155562306a36Sopenharmony_ci * Analyze taskfile of @qc and further determine cause of 155662306a36Sopenharmony_ci * failure. This function also requests ATAPI sense data if 155762306a36Sopenharmony_ci * available. 155862306a36Sopenharmony_ci * 155962306a36Sopenharmony_ci * LOCKING: 156062306a36Sopenharmony_ci * Kernel thread context (may sleep). 156162306a36Sopenharmony_ci * 156262306a36Sopenharmony_ci * RETURNS: 156362306a36Sopenharmony_ci * Determined recovery action 156462306a36Sopenharmony_ci */ 156562306a36Sopenharmony_cistatic unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc) 156662306a36Sopenharmony_ci{ 156762306a36Sopenharmony_ci const struct ata_taskfile *tf = &qc->result_tf; 156862306a36Sopenharmony_ci unsigned int tmp, action = 0; 156962306a36Sopenharmony_ci u8 stat = tf->status, err = tf->error; 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) { 157262306a36Sopenharmony_ci qc->err_mask |= AC_ERR_HSM; 157362306a36Sopenharmony_ci return ATA_EH_RESET; 157462306a36Sopenharmony_ci } 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if (stat & (ATA_ERR | ATA_DF)) { 157762306a36Sopenharmony_ci qc->err_mask |= AC_ERR_DEV; 157862306a36Sopenharmony_ci /* 157962306a36Sopenharmony_ci * Sense data reporting does not work if the 158062306a36Sopenharmony_ci * device fault bit is set. 158162306a36Sopenharmony_ci */ 158262306a36Sopenharmony_ci if (stat & ATA_DF) 158362306a36Sopenharmony_ci stat &= ~ATA_SENSE; 158462306a36Sopenharmony_ci } else { 158562306a36Sopenharmony_ci return 0; 158662306a36Sopenharmony_ci } 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ci switch (qc->dev->class) { 158962306a36Sopenharmony_ci case ATA_DEV_ATA: 159062306a36Sopenharmony_ci case ATA_DEV_ZAC: 159162306a36Sopenharmony_ci /* 159262306a36Sopenharmony_ci * Fetch the sense data explicitly if: 159362306a36Sopenharmony_ci * -It was a non-NCQ command that failed, or 159462306a36Sopenharmony_ci * -It was a NCQ command that failed, but the sense data 159562306a36Sopenharmony_ci * was not included in the NCQ command error log 159662306a36Sopenharmony_ci * (i.e. NCQ autosense is not supported by the device). 159762306a36Sopenharmony_ci */ 159862306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_SENSE_VALID) && 159962306a36Sopenharmony_ci (stat & ATA_SENSE) && ata_eh_request_sense(qc)) 160062306a36Sopenharmony_ci set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION); 160162306a36Sopenharmony_ci if (err & ATA_ICRC) 160262306a36Sopenharmony_ci qc->err_mask |= AC_ERR_ATA_BUS; 160362306a36Sopenharmony_ci if (err & (ATA_UNC | ATA_AMNF)) 160462306a36Sopenharmony_ci qc->err_mask |= AC_ERR_MEDIA; 160562306a36Sopenharmony_ci if (err & ATA_IDNF) 160662306a36Sopenharmony_ci qc->err_mask |= AC_ERR_INVALID; 160762306a36Sopenharmony_ci break; 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci case ATA_DEV_ATAPI: 161062306a36Sopenharmony_ci if (!ata_port_is_frozen(qc->ap)) { 161162306a36Sopenharmony_ci tmp = atapi_eh_request_sense(qc->dev, 161262306a36Sopenharmony_ci qc->scsicmd->sense_buffer, 161362306a36Sopenharmony_ci qc->result_tf.error >> 4); 161462306a36Sopenharmony_ci if (!tmp) 161562306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_SENSE_VALID; 161662306a36Sopenharmony_ci else 161762306a36Sopenharmony_ci qc->err_mask |= tmp; 161862306a36Sopenharmony_ci } 161962306a36Sopenharmony_ci } 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_SENSE_VALID) { 162262306a36Sopenharmony_ci enum scsi_disposition ret = scsi_check_sense(qc->scsicmd); 162362306a36Sopenharmony_ci /* 162462306a36Sopenharmony_ci * SUCCESS here means that the sense code could be 162562306a36Sopenharmony_ci * evaluated and should be passed to the upper layers 162662306a36Sopenharmony_ci * for correct evaluation. 162762306a36Sopenharmony_ci * FAILED means the sense code could not be interpreted 162862306a36Sopenharmony_ci * and the device would need to be reset. 162962306a36Sopenharmony_ci * NEEDS_RETRY and ADD_TO_MLQUEUE means that the 163062306a36Sopenharmony_ci * command would need to be retried. 163162306a36Sopenharmony_ci */ 163262306a36Sopenharmony_ci if (ret == NEEDS_RETRY || ret == ADD_TO_MLQUEUE) { 163362306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_RETRY; 163462306a36Sopenharmony_ci qc->err_mask |= AC_ERR_OTHER; 163562306a36Sopenharmony_ci } else if (ret != SUCCESS) { 163662306a36Sopenharmony_ci qc->err_mask |= AC_ERR_HSM; 163762306a36Sopenharmony_ci } 163862306a36Sopenharmony_ci } 163962306a36Sopenharmony_ci if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) 164062306a36Sopenharmony_ci action |= ATA_EH_RESET; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci return action; 164362306a36Sopenharmony_ci} 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_cistatic int ata_eh_categorize_error(unsigned int eflags, unsigned int err_mask, 164662306a36Sopenharmony_ci int *xfer_ok) 164762306a36Sopenharmony_ci{ 164862306a36Sopenharmony_ci int base = 0; 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci if (!(eflags & ATA_EFLAG_DUBIOUS_XFER)) 165162306a36Sopenharmony_ci *xfer_ok = 1; 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_ci if (!*xfer_ok) 165462306a36Sopenharmony_ci base = ATA_ECAT_DUBIOUS_NONE; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci if (err_mask & AC_ERR_ATA_BUS) 165762306a36Sopenharmony_ci return base + ATA_ECAT_ATA_BUS; 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci if (err_mask & AC_ERR_TIMEOUT) 166062306a36Sopenharmony_ci return base + ATA_ECAT_TOUT_HSM; 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci if (eflags & ATA_EFLAG_IS_IO) { 166362306a36Sopenharmony_ci if (err_mask & AC_ERR_HSM) 166462306a36Sopenharmony_ci return base + ATA_ECAT_TOUT_HSM; 166562306a36Sopenharmony_ci if ((err_mask & 166662306a36Sopenharmony_ci (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV) 166762306a36Sopenharmony_ci return base + ATA_ECAT_UNK_DEV; 166862306a36Sopenharmony_ci } 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci return 0; 167162306a36Sopenharmony_ci} 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_cistruct speed_down_verdict_arg { 167462306a36Sopenharmony_ci u64 since; 167562306a36Sopenharmony_ci int xfer_ok; 167662306a36Sopenharmony_ci int nr_errors[ATA_ECAT_NR]; 167762306a36Sopenharmony_ci}; 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_cistatic int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) 168062306a36Sopenharmony_ci{ 168162306a36Sopenharmony_ci struct speed_down_verdict_arg *arg = void_arg; 168262306a36Sopenharmony_ci int cat; 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since)) 168562306a36Sopenharmony_ci return -1; 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_ci cat = ata_eh_categorize_error(ent->eflags, ent->err_mask, 168862306a36Sopenharmony_ci &arg->xfer_ok); 168962306a36Sopenharmony_ci arg->nr_errors[cat]++; 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci return 0; 169262306a36Sopenharmony_ci} 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci/** 169562306a36Sopenharmony_ci * ata_eh_speed_down_verdict - Determine speed down verdict 169662306a36Sopenharmony_ci * @dev: Device of interest 169762306a36Sopenharmony_ci * 169862306a36Sopenharmony_ci * This function examines error ring of @dev and determines 169962306a36Sopenharmony_ci * whether NCQ needs to be turned off, transfer speed should be 170062306a36Sopenharmony_ci * stepped down, or falling back to PIO is necessary. 170162306a36Sopenharmony_ci * 170262306a36Sopenharmony_ci * ECAT_ATA_BUS : ATA_BUS error for any command 170362306a36Sopenharmony_ci * 170462306a36Sopenharmony_ci * ECAT_TOUT_HSM : TIMEOUT for any command or HSM violation for 170562306a36Sopenharmony_ci * IO commands 170662306a36Sopenharmony_ci * 170762306a36Sopenharmony_ci * ECAT_UNK_DEV : Unknown DEV error for IO commands 170862306a36Sopenharmony_ci * 170962306a36Sopenharmony_ci * ECAT_DUBIOUS_* : Identical to above three but occurred while 171062306a36Sopenharmony_ci * data transfer hasn't been verified. 171162306a36Sopenharmony_ci * 171262306a36Sopenharmony_ci * Verdicts are 171362306a36Sopenharmony_ci * 171462306a36Sopenharmony_ci * NCQ_OFF : Turn off NCQ. 171562306a36Sopenharmony_ci * 171662306a36Sopenharmony_ci * SPEED_DOWN : Speed down transfer speed but don't fall back 171762306a36Sopenharmony_ci * to PIO. 171862306a36Sopenharmony_ci * 171962306a36Sopenharmony_ci * FALLBACK_TO_PIO : Fall back to PIO. 172062306a36Sopenharmony_ci * 172162306a36Sopenharmony_ci * Even if multiple verdicts are returned, only one action is 172262306a36Sopenharmony_ci * taken per error. An action triggered by non-DUBIOUS errors 172362306a36Sopenharmony_ci * clears ering, while one triggered by DUBIOUS_* errors doesn't. 172462306a36Sopenharmony_ci * This is to expedite speed down decisions right after device is 172562306a36Sopenharmony_ci * initially configured. 172662306a36Sopenharmony_ci * 172762306a36Sopenharmony_ci * The following are speed down rules. #1 and #2 deal with 172862306a36Sopenharmony_ci * DUBIOUS errors. 172962306a36Sopenharmony_ci * 173062306a36Sopenharmony_ci * 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors 173162306a36Sopenharmony_ci * occurred during last 5 mins, SPEED_DOWN and FALLBACK_TO_PIO. 173262306a36Sopenharmony_ci * 173362306a36Sopenharmony_ci * 2. If more than one DUBIOUS_TOUT_HSM or DUBIOUS_UNK_DEV errors 173462306a36Sopenharmony_ci * occurred during last 5 mins, NCQ_OFF. 173562306a36Sopenharmony_ci * 173662306a36Sopenharmony_ci * 3. If more than 8 ATA_BUS, TOUT_HSM or UNK_DEV errors 173762306a36Sopenharmony_ci * occurred during last 5 mins, FALLBACK_TO_PIO 173862306a36Sopenharmony_ci * 173962306a36Sopenharmony_ci * 4. If more than 3 TOUT_HSM or UNK_DEV errors occurred 174062306a36Sopenharmony_ci * during last 10 mins, NCQ_OFF. 174162306a36Sopenharmony_ci * 174262306a36Sopenharmony_ci * 5. If more than 3 ATA_BUS or TOUT_HSM errors, or more than 6 174362306a36Sopenharmony_ci * UNK_DEV errors occurred during last 10 mins, SPEED_DOWN. 174462306a36Sopenharmony_ci * 174562306a36Sopenharmony_ci * LOCKING: 174662306a36Sopenharmony_ci * Inherited from caller. 174762306a36Sopenharmony_ci * 174862306a36Sopenharmony_ci * RETURNS: 174962306a36Sopenharmony_ci * OR of ATA_EH_SPDN_* flags. 175062306a36Sopenharmony_ci */ 175162306a36Sopenharmony_cistatic unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) 175262306a36Sopenharmony_ci{ 175362306a36Sopenharmony_ci const u64 j5mins = 5LLU * 60 * HZ, j10mins = 10LLU * 60 * HZ; 175462306a36Sopenharmony_ci u64 j64 = get_jiffies_64(); 175562306a36Sopenharmony_ci struct speed_down_verdict_arg arg; 175662306a36Sopenharmony_ci unsigned int verdict = 0; 175762306a36Sopenharmony_ci 175862306a36Sopenharmony_ci /* scan past 5 mins of error history */ 175962306a36Sopenharmony_ci memset(&arg, 0, sizeof(arg)); 176062306a36Sopenharmony_ci arg.since = j64 - min(j64, j5mins); 176162306a36Sopenharmony_ci ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci if (arg.nr_errors[ATA_ECAT_DUBIOUS_ATA_BUS] + 176462306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] > 1) 176562306a36Sopenharmony_ci verdict |= ATA_EH_SPDN_SPEED_DOWN | 176662306a36Sopenharmony_ci ATA_EH_SPDN_FALLBACK_TO_PIO | ATA_EH_SPDN_KEEP_ERRORS; 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_ci if (arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] + 176962306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_DUBIOUS_UNK_DEV] > 1) 177062306a36Sopenharmony_ci verdict |= ATA_EH_SPDN_NCQ_OFF | ATA_EH_SPDN_KEEP_ERRORS; 177162306a36Sopenharmony_ci 177262306a36Sopenharmony_ci if (arg.nr_errors[ATA_ECAT_ATA_BUS] + 177362306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_TOUT_HSM] + 177462306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_UNK_DEV] > 6) 177562306a36Sopenharmony_ci verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO; 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ci /* scan past 10 mins of error history */ 177862306a36Sopenharmony_ci memset(&arg, 0, sizeof(arg)); 177962306a36Sopenharmony_ci arg.since = j64 - min(j64, j10mins); 178062306a36Sopenharmony_ci ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci if (arg.nr_errors[ATA_ECAT_TOUT_HSM] + 178362306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_UNK_DEV] > 3) 178462306a36Sopenharmony_ci verdict |= ATA_EH_SPDN_NCQ_OFF; 178562306a36Sopenharmony_ci 178662306a36Sopenharmony_ci if (arg.nr_errors[ATA_ECAT_ATA_BUS] + 178762306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_TOUT_HSM] > 3 || 178862306a36Sopenharmony_ci arg.nr_errors[ATA_ECAT_UNK_DEV] > 6) 178962306a36Sopenharmony_ci verdict |= ATA_EH_SPDN_SPEED_DOWN; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci return verdict; 179262306a36Sopenharmony_ci} 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci/** 179562306a36Sopenharmony_ci * ata_eh_speed_down - record error and speed down if necessary 179662306a36Sopenharmony_ci * @dev: Failed device 179762306a36Sopenharmony_ci * @eflags: mask of ATA_EFLAG_* flags 179862306a36Sopenharmony_ci * @err_mask: err_mask of the error 179962306a36Sopenharmony_ci * 180062306a36Sopenharmony_ci * Record error and examine error history to determine whether 180162306a36Sopenharmony_ci * adjusting transmission speed is necessary. It also sets 180262306a36Sopenharmony_ci * transmission limits appropriately if such adjustment is 180362306a36Sopenharmony_ci * necessary. 180462306a36Sopenharmony_ci * 180562306a36Sopenharmony_ci * LOCKING: 180662306a36Sopenharmony_ci * Kernel thread context (may sleep). 180762306a36Sopenharmony_ci * 180862306a36Sopenharmony_ci * RETURNS: 180962306a36Sopenharmony_ci * Determined recovery action. 181062306a36Sopenharmony_ci */ 181162306a36Sopenharmony_cistatic unsigned int ata_eh_speed_down(struct ata_device *dev, 181262306a36Sopenharmony_ci unsigned int eflags, unsigned int err_mask) 181362306a36Sopenharmony_ci{ 181462306a36Sopenharmony_ci struct ata_link *link = ata_dev_phys_link(dev); 181562306a36Sopenharmony_ci int xfer_ok = 0; 181662306a36Sopenharmony_ci unsigned int verdict; 181762306a36Sopenharmony_ci unsigned int action = 0; 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci /* don't bother if Cat-0 error */ 182062306a36Sopenharmony_ci if (ata_eh_categorize_error(eflags, err_mask, &xfer_ok) == 0) 182162306a36Sopenharmony_ci return 0; 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci /* record error and determine whether speed down is necessary */ 182462306a36Sopenharmony_ci ata_ering_record(&dev->ering, eflags, err_mask); 182562306a36Sopenharmony_ci verdict = ata_eh_speed_down_verdict(dev); 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci /* turn off NCQ? */ 182862306a36Sopenharmony_ci if ((verdict & ATA_EH_SPDN_NCQ_OFF) && ata_ncq_enabled(dev)) { 182962306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_NCQ_OFF; 183062306a36Sopenharmony_ci ata_dev_warn(dev, "NCQ disabled due to excessive errors\n"); 183162306a36Sopenharmony_ci goto done; 183262306a36Sopenharmony_ci } 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci /* speed down? */ 183562306a36Sopenharmony_ci if (verdict & ATA_EH_SPDN_SPEED_DOWN) { 183662306a36Sopenharmony_ci /* speed down SATA link speed if possible */ 183762306a36Sopenharmony_ci if (sata_down_spd_limit(link, 0) == 0) { 183862306a36Sopenharmony_ci action |= ATA_EH_RESET; 183962306a36Sopenharmony_ci goto done; 184062306a36Sopenharmony_ci } 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci /* lower transfer mode */ 184362306a36Sopenharmony_ci if (dev->spdn_cnt < 2) { 184462306a36Sopenharmony_ci static const int dma_dnxfer_sel[] = 184562306a36Sopenharmony_ci { ATA_DNXFER_DMA, ATA_DNXFER_40C }; 184662306a36Sopenharmony_ci static const int pio_dnxfer_sel[] = 184762306a36Sopenharmony_ci { ATA_DNXFER_PIO, ATA_DNXFER_FORCE_PIO0 }; 184862306a36Sopenharmony_ci int sel; 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci if (dev->xfer_shift != ATA_SHIFT_PIO) 185162306a36Sopenharmony_ci sel = dma_dnxfer_sel[dev->spdn_cnt]; 185262306a36Sopenharmony_ci else 185362306a36Sopenharmony_ci sel = pio_dnxfer_sel[dev->spdn_cnt]; 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci dev->spdn_cnt++; 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci if (ata_down_xfermask_limit(dev, sel) == 0) { 185862306a36Sopenharmony_ci action |= ATA_EH_RESET; 185962306a36Sopenharmony_ci goto done; 186062306a36Sopenharmony_ci } 186162306a36Sopenharmony_ci } 186262306a36Sopenharmony_ci } 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_ci /* Fall back to PIO? Slowing down to PIO is meaningless for 186562306a36Sopenharmony_ci * SATA ATA devices. Consider it only for PATA and SATAPI. 186662306a36Sopenharmony_ci */ 186762306a36Sopenharmony_ci if ((verdict & ATA_EH_SPDN_FALLBACK_TO_PIO) && (dev->spdn_cnt >= 2) && 186862306a36Sopenharmony_ci (link->ap->cbl != ATA_CBL_SATA || dev->class == ATA_DEV_ATAPI) && 186962306a36Sopenharmony_ci (dev->xfer_shift != ATA_SHIFT_PIO)) { 187062306a36Sopenharmony_ci if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) { 187162306a36Sopenharmony_ci dev->spdn_cnt = 0; 187262306a36Sopenharmony_ci action |= ATA_EH_RESET; 187362306a36Sopenharmony_ci goto done; 187462306a36Sopenharmony_ci } 187562306a36Sopenharmony_ci } 187662306a36Sopenharmony_ci 187762306a36Sopenharmony_ci return 0; 187862306a36Sopenharmony_ci done: 187962306a36Sopenharmony_ci /* device has been slowed down, blow error history */ 188062306a36Sopenharmony_ci if (!(verdict & ATA_EH_SPDN_KEEP_ERRORS)) 188162306a36Sopenharmony_ci ata_ering_clear(&dev->ering); 188262306a36Sopenharmony_ci return action; 188362306a36Sopenharmony_ci} 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci/** 188662306a36Sopenharmony_ci * ata_eh_worth_retry - analyze error and decide whether to retry 188762306a36Sopenharmony_ci * @qc: qc to possibly retry 188862306a36Sopenharmony_ci * 188962306a36Sopenharmony_ci * Look at the cause of the error and decide if a retry 189062306a36Sopenharmony_ci * might be useful or not. We don't want to retry media errors 189162306a36Sopenharmony_ci * because the drive itself has probably already taken 10-30 seconds 189262306a36Sopenharmony_ci * doing its own internal retries before reporting the failure. 189362306a36Sopenharmony_ci */ 189462306a36Sopenharmony_cistatic inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) 189562306a36Sopenharmony_ci{ 189662306a36Sopenharmony_ci if (qc->err_mask & AC_ERR_MEDIA) 189762306a36Sopenharmony_ci return 0; /* don't retry media errors */ 189862306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_IO) 189962306a36Sopenharmony_ci return 1; /* otherwise retry anything from fs stack */ 190062306a36Sopenharmony_ci if (qc->err_mask & AC_ERR_INVALID) 190162306a36Sopenharmony_ci return 0; /* don't retry these */ 190262306a36Sopenharmony_ci return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */ 190362306a36Sopenharmony_ci} 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci/** 190662306a36Sopenharmony_ci * ata_eh_quiet - check if we need to be quiet about a command error 190762306a36Sopenharmony_ci * @qc: qc to check 190862306a36Sopenharmony_ci * 190962306a36Sopenharmony_ci * Look at the qc flags anbd its scsi command request flags to determine 191062306a36Sopenharmony_ci * if we need to be quiet about the command failure. 191162306a36Sopenharmony_ci */ 191262306a36Sopenharmony_cistatic inline bool ata_eh_quiet(struct ata_queued_cmd *qc) 191362306a36Sopenharmony_ci{ 191462306a36Sopenharmony_ci if (qc->scsicmd && scsi_cmd_to_rq(qc->scsicmd)->rq_flags & RQF_QUIET) 191562306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_QUIET; 191662306a36Sopenharmony_ci return qc->flags & ATA_QCFLAG_QUIET; 191762306a36Sopenharmony_ci} 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_cistatic int ata_eh_read_sense_success_non_ncq(struct ata_link *link) 192062306a36Sopenharmony_ci{ 192162306a36Sopenharmony_ci struct ata_port *ap = link->ap; 192262306a36Sopenharmony_ci struct ata_queued_cmd *qc; 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci qc = __ata_qc_from_tag(ap, link->active_tag); 192562306a36Sopenharmony_ci if (!qc) 192662306a36Sopenharmony_ci return -EIO; 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH) || 192962306a36Sopenharmony_ci !(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) || 193062306a36Sopenharmony_ci qc->err_mask) 193162306a36Sopenharmony_ci return -EIO; 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci if (!ata_eh_request_sense(qc)) 193462306a36Sopenharmony_ci return -EIO; 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci /* 193762306a36Sopenharmony_ci * If we have sense data, call scsi_check_sense() in order to set the 193862306a36Sopenharmony_ci * correct SCSI ML byte (if any). No point in checking the return value, 193962306a36Sopenharmony_ci * since the command has already completed successfully. 194062306a36Sopenharmony_ci */ 194162306a36Sopenharmony_ci scsi_check_sense(qc->scsicmd); 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci return 0; 194462306a36Sopenharmony_ci} 194562306a36Sopenharmony_ci 194662306a36Sopenharmony_cistatic void ata_eh_get_success_sense(struct ata_link *link) 194762306a36Sopenharmony_ci{ 194862306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 194962306a36Sopenharmony_ci struct ata_device *dev = link->device; 195062306a36Sopenharmony_ci struct ata_port *ap = link->ap; 195162306a36Sopenharmony_ci struct ata_queued_cmd *qc; 195262306a36Sopenharmony_ci int tag, ret = 0; 195362306a36Sopenharmony_ci 195462306a36Sopenharmony_ci if (!(ehc->i.dev_action[dev->devno] & ATA_EH_GET_SUCCESS_SENSE)) 195562306a36Sopenharmony_ci return; 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci /* if frozen, we can't do much */ 195862306a36Sopenharmony_ci if (ata_port_is_frozen(ap)) { 195962306a36Sopenharmony_ci ata_dev_warn(dev, 196062306a36Sopenharmony_ci "successful sense data available but port frozen\n"); 196162306a36Sopenharmony_ci goto out; 196262306a36Sopenharmony_ci } 196362306a36Sopenharmony_ci 196462306a36Sopenharmony_ci /* 196562306a36Sopenharmony_ci * If the link has sactive set, then we have outstanding NCQ commands 196662306a36Sopenharmony_ci * and have to read the Successful NCQ Commands log to get the sense 196762306a36Sopenharmony_ci * data. Otherwise, we are dealing with a non-NCQ command and use 196862306a36Sopenharmony_ci * request sense ext command to retrieve the sense data. 196962306a36Sopenharmony_ci */ 197062306a36Sopenharmony_ci if (link->sactive) 197162306a36Sopenharmony_ci ret = ata_eh_read_sense_success_ncq_log(link); 197262306a36Sopenharmony_ci else 197362306a36Sopenharmony_ci ret = ata_eh_read_sense_success_non_ncq(link); 197462306a36Sopenharmony_ci if (ret) 197562306a36Sopenharmony_ci goto out; 197662306a36Sopenharmony_ci 197762306a36Sopenharmony_ci ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE); 197862306a36Sopenharmony_ci return; 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_ciout: 198162306a36Sopenharmony_ci /* 198262306a36Sopenharmony_ci * If we failed to get sense data for a successful command that ought to 198362306a36Sopenharmony_ci * have sense data, we cannot simply return BLK_STS_OK to user space. 198462306a36Sopenharmony_ci * This is because we can't know if the sense data that we couldn't get 198562306a36Sopenharmony_ci * was actually "DATA CURRENTLY UNAVAILABLE". Reporting such a command 198662306a36Sopenharmony_ci * as success to user space would result in a silent data corruption. 198762306a36Sopenharmony_ci * Thus, add a bogus ABORTED_COMMAND sense data to such commands, such 198862306a36Sopenharmony_ci * that SCSI will report these commands as BLK_STS_IOERR to user space. 198962306a36Sopenharmony_ci */ 199062306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, tag) { 199162306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH) || 199262306a36Sopenharmony_ci !(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) || 199362306a36Sopenharmony_ci qc->err_mask || 199462306a36Sopenharmony_ci ata_dev_phys_link(qc->dev) != link) 199562306a36Sopenharmony_ci continue; 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci /* We managed to get sense for this success command, skip. */ 199862306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_SENSE_VALID) 199962306a36Sopenharmony_ci continue; 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci /* This success command did not have any sense data, skip. */ 200262306a36Sopenharmony_ci if (!(qc->result_tf.status & ATA_SENSE)) 200362306a36Sopenharmony_ci continue; 200462306a36Sopenharmony_ci 200562306a36Sopenharmony_ci /* This success command had sense data, but we failed to get. */ 200662306a36Sopenharmony_ci ata_scsi_set_sense(dev, qc->scsicmd, ABORTED_COMMAND, 0, 0); 200762306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_SENSE_VALID; 200862306a36Sopenharmony_ci } 200962306a36Sopenharmony_ci ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE); 201062306a36Sopenharmony_ci} 201162306a36Sopenharmony_ci 201262306a36Sopenharmony_ci/** 201362306a36Sopenharmony_ci * ata_eh_link_autopsy - analyze error and determine recovery action 201462306a36Sopenharmony_ci * @link: host link to perform autopsy on 201562306a36Sopenharmony_ci * 201662306a36Sopenharmony_ci * Analyze why @link failed and determine which recovery actions 201762306a36Sopenharmony_ci * are needed. This function also sets more detailed AC_ERR_* 201862306a36Sopenharmony_ci * values and fills sense data for ATAPI CHECK SENSE. 201962306a36Sopenharmony_ci * 202062306a36Sopenharmony_ci * LOCKING: 202162306a36Sopenharmony_ci * Kernel thread context (may sleep). 202262306a36Sopenharmony_ci */ 202362306a36Sopenharmony_cistatic void ata_eh_link_autopsy(struct ata_link *link) 202462306a36Sopenharmony_ci{ 202562306a36Sopenharmony_ci struct ata_port *ap = link->ap; 202662306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 202762306a36Sopenharmony_ci struct ata_queued_cmd *qc; 202862306a36Sopenharmony_ci struct ata_device *dev; 202962306a36Sopenharmony_ci unsigned int all_err_mask = 0, eflags = 0; 203062306a36Sopenharmony_ci int tag, nr_failed = 0, nr_quiet = 0; 203162306a36Sopenharmony_ci u32 serror; 203262306a36Sopenharmony_ci int rc; 203362306a36Sopenharmony_ci 203462306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_NO_AUTOPSY) 203562306a36Sopenharmony_ci return; 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci /* obtain and analyze SError */ 203862306a36Sopenharmony_ci rc = sata_scr_read(link, SCR_ERROR, &serror); 203962306a36Sopenharmony_ci if (rc == 0) { 204062306a36Sopenharmony_ci ehc->i.serror |= serror; 204162306a36Sopenharmony_ci ata_eh_analyze_serror(link); 204262306a36Sopenharmony_ci } else if (rc != -EOPNOTSUPP) { 204362306a36Sopenharmony_ci /* SError read failed, force reset and probing */ 204462306a36Sopenharmony_ci ehc->i.probe_mask |= ATA_ALL_DEVICES; 204562306a36Sopenharmony_ci ehc->i.action |= ATA_EH_RESET; 204662306a36Sopenharmony_ci ehc->i.err_mask |= AC_ERR_OTHER; 204762306a36Sopenharmony_ci } 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci /* analyze NCQ failure */ 205062306a36Sopenharmony_ci ata_eh_analyze_ncq_error(link); 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_ci /* 205362306a36Sopenharmony_ci * Check if this was a successful command that simply needs sense data. 205462306a36Sopenharmony_ci * Since the sense data is not part of the completion, we need to fetch 205562306a36Sopenharmony_ci * it using an additional command. Since this can't be done from irq 205662306a36Sopenharmony_ci * context, the sense data for successful commands are fetched by EH. 205762306a36Sopenharmony_ci */ 205862306a36Sopenharmony_ci ata_eh_get_success_sense(link); 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci /* any real error trumps AC_ERR_OTHER */ 206162306a36Sopenharmony_ci if (ehc->i.err_mask & ~AC_ERR_OTHER) 206262306a36Sopenharmony_ci ehc->i.err_mask &= ~AC_ERR_OTHER; 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci all_err_mask |= ehc->i.err_mask; 206562306a36Sopenharmony_ci 206662306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, tag) { 206762306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH) || 206862306a36Sopenharmony_ci qc->flags & ATA_QCFLAG_RETRY || 206962306a36Sopenharmony_ci qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD || 207062306a36Sopenharmony_ci ata_dev_phys_link(qc->dev) != link) 207162306a36Sopenharmony_ci continue; 207262306a36Sopenharmony_ci 207362306a36Sopenharmony_ci /* inherit upper level err_mask */ 207462306a36Sopenharmony_ci qc->err_mask |= ehc->i.err_mask; 207562306a36Sopenharmony_ci 207662306a36Sopenharmony_ci /* analyze TF */ 207762306a36Sopenharmony_ci ehc->i.action |= ata_eh_analyze_tf(qc); 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci /* DEV errors are probably spurious in case of ATA_BUS error */ 208062306a36Sopenharmony_ci if (qc->err_mask & AC_ERR_ATA_BUS) 208162306a36Sopenharmony_ci qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_MEDIA | 208262306a36Sopenharmony_ci AC_ERR_INVALID); 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci /* any real error trumps unknown error */ 208562306a36Sopenharmony_ci if (qc->err_mask & ~AC_ERR_OTHER) 208662306a36Sopenharmony_ci qc->err_mask &= ~AC_ERR_OTHER; 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci /* 208962306a36Sopenharmony_ci * SENSE_VALID trumps dev/unknown error and revalidation. Upper 209062306a36Sopenharmony_ci * layers will determine whether the command is worth retrying 209162306a36Sopenharmony_ci * based on the sense data and device class/type. Otherwise, 209262306a36Sopenharmony_ci * determine directly if the command is worth retrying using its 209362306a36Sopenharmony_ci * error mask and flags. 209462306a36Sopenharmony_ci */ 209562306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_SENSE_VALID) 209662306a36Sopenharmony_ci qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); 209762306a36Sopenharmony_ci else if (ata_eh_worth_retry(qc)) 209862306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_RETRY; 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci /* accumulate error info */ 210162306a36Sopenharmony_ci ehc->i.dev = qc->dev; 210262306a36Sopenharmony_ci all_err_mask |= qc->err_mask; 210362306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_IO) 210462306a36Sopenharmony_ci eflags |= ATA_EFLAG_IS_IO; 210562306a36Sopenharmony_ci trace_ata_eh_link_autopsy_qc(qc); 210662306a36Sopenharmony_ci 210762306a36Sopenharmony_ci /* Count quiet errors */ 210862306a36Sopenharmony_ci if (ata_eh_quiet(qc)) 210962306a36Sopenharmony_ci nr_quiet++; 211062306a36Sopenharmony_ci nr_failed++; 211162306a36Sopenharmony_ci } 211262306a36Sopenharmony_ci 211362306a36Sopenharmony_ci /* If all failed commands requested silence, then be quiet */ 211462306a36Sopenharmony_ci if (nr_quiet == nr_failed) 211562306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_QUIET; 211662306a36Sopenharmony_ci 211762306a36Sopenharmony_ci /* enforce default EH actions */ 211862306a36Sopenharmony_ci if (ata_port_is_frozen(ap) || 211962306a36Sopenharmony_ci all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) 212062306a36Sopenharmony_ci ehc->i.action |= ATA_EH_RESET; 212162306a36Sopenharmony_ci else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) || 212262306a36Sopenharmony_ci (!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV))) 212362306a36Sopenharmony_ci ehc->i.action |= ATA_EH_REVALIDATE; 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci /* If we have offending qcs and the associated failed device, 212662306a36Sopenharmony_ci * perform per-dev EH action only on the offending device. 212762306a36Sopenharmony_ci */ 212862306a36Sopenharmony_ci if (ehc->i.dev) { 212962306a36Sopenharmony_ci ehc->i.dev_action[ehc->i.dev->devno] |= 213062306a36Sopenharmony_ci ehc->i.action & ATA_EH_PERDEV_MASK; 213162306a36Sopenharmony_ci ehc->i.action &= ~ATA_EH_PERDEV_MASK; 213262306a36Sopenharmony_ci } 213362306a36Sopenharmony_ci 213462306a36Sopenharmony_ci /* propagate timeout to host link */ 213562306a36Sopenharmony_ci if ((all_err_mask & AC_ERR_TIMEOUT) && !ata_is_host_link(link)) 213662306a36Sopenharmony_ci ap->link.eh_context.i.err_mask |= AC_ERR_TIMEOUT; 213762306a36Sopenharmony_ci 213862306a36Sopenharmony_ci /* record error and consider speeding down */ 213962306a36Sopenharmony_ci dev = ehc->i.dev; 214062306a36Sopenharmony_ci if (!dev && ((ata_link_max_devices(link) == 1 && 214162306a36Sopenharmony_ci ata_dev_enabled(link->device)))) 214262306a36Sopenharmony_ci dev = link->device; 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci if (dev) { 214562306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_DUBIOUS_XFER) 214662306a36Sopenharmony_ci eflags |= ATA_EFLAG_DUBIOUS_XFER; 214762306a36Sopenharmony_ci ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask); 214862306a36Sopenharmony_ci trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask); 214962306a36Sopenharmony_ci } 215062306a36Sopenharmony_ci} 215162306a36Sopenharmony_ci 215262306a36Sopenharmony_ci/** 215362306a36Sopenharmony_ci * ata_eh_autopsy - analyze error and determine recovery action 215462306a36Sopenharmony_ci * @ap: host port to perform autopsy on 215562306a36Sopenharmony_ci * 215662306a36Sopenharmony_ci * Analyze all links of @ap and determine why they failed and 215762306a36Sopenharmony_ci * which recovery actions are needed. 215862306a36Sopenharmony_ci * 215962306a36Sopenharmony_ci * LOCKING: 216062306a36Sopenharmony_ci * Kernel thread context (may sleep). 216162306a36Sopenharmony_ci */ 216262306a36Sopenharmony_civoid ata_eh_autopsy(struct ata_port *ap) 216362306a36Sopenharmony_ci{ 216462306a36Sopenharmony_ci struct ata_link *link; 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) 216762306a36Sopenharmony_ci ata_eh_link_autopsy(link); 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_ci /* Handle the frigging slave link. Autopsy is done similarly 217062306a36Sopenharmony_ci * but actions and flags are transferred over to the master 217162306a36Sopenharmony_ci * link and handled from there. 217262306a36Sopenharmony_ci */ 217362306a36Sopenharmony_ci if (ap->slave_link) { 217462306a36Sopenharmony_ci struct ata_eh_context *mehc = &ap->link.eh_context; 217562306a36Sopenharmony_ci struct ata_eh_context *sehc = &ap->slave_link->eh_context; 217662306a36Sopenharmony_ci 217762306a36Sopenharmony_ci /* transfer control flags from master to slave */ 217862306a36Sopenharmony_ci sehc->i.flags |= mehc->i.flags & ATA_EHI_TO_SLAVE_MASK; 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_ci /* perform autopsy on the slave link */ 218162306a36Sopenharmony_ci ata_eh_link_autopsy(ap->slave_link); 218262306a36Sopenharmony_ci 218362306a36Sopenharmony_ci /* transfer actions from slave to master and clear slave */ 218462306a36Sopenharmony_ci ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS); 218562306a36Sopenharmony_ci mehc->i.action |= sehc->i.action; 218662306a36Sopenharmony_ci mehc->i.dev_action[1] |= sehc->i.dev_action[1]; 218762306a36Sopenharmony_ci mehc->i.flags |= sehc->i.flags; 218862306a36Sopenharmony_ci ata_eh_done(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS); 218962306a36Sopenharmony_ci } 219062306a36Sopenharmony_ci 219162306a36Sopenharmony_ci /* Autopsy of fanout ports can affect host link autopsy. 219262306a36Sopenharmony_ci * Perform host link autopsy last. 219362306a36Sopenharmony_ci */ 219462306a36Sopenharmony_ci if (sata_pmp_attached(ap)) 219562306a36Sopenharmony_ci ata_eh_link_autopsy(&ap->link); 219662306a36Sopenharmony_ci} 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci/** 219962306a36Sopenharmony_ci * ata_get_cmd_name - get name for ATA command 220062306a36Sopenharmony_ci * @command: ATA command code to get name for 220162306a36Sopenharmony_ci * 220262306a36Sopenharmony_ci * Return a textual name of the given command or "unknown" 220362306a36Sopenharmony_ci * 220462306a36Sopenharmony_ci * LOCKING: 220562306a36Sopenharmony_ci * None 220662306a36Sopenharmony_ci */ 220762306a36Sopenharmony_ciconst char *ata_get_cmd_name(u8 command) 220862306a36Sopenharmony_ci{ 220962306a36Sopenharmony_ci#ifdef CONFIG_ATA_VERBOSE_ERROR 221062306a36Sopenharmony_ci static const struct 221162306a36Sopenharmony_ci { 221262306a36Sopenharmony_ci u8 command; 221362306a36Sopenharmony_ci const char *text; 221462306a36Sopenharmony_ci } cmd_descr[] = { 221562306a36Sopenharmony_ci { ATA_CMD_DEV_RESET, "DEVICE RESET" }, 221662306a36Sopenharmony_ci { ATA_CMD_CHK_POWER, "CHECK POWER MODE" }, 221762306a36Sopenharmony_ci { ATA_CMD_STANDBY, "STANDBY" }, 221862306a36Sopenharmony_ci { ATA_CMD_IDLE, "IDLE" }, 221962306a36Sopenharmony_ci { ATA_CMD_EDD, "EXECUTE DEVICE DIAGNOSTIC" }, 222062306a36Sopenharmony_ci { ATA_CMD_DOWNLOAD_MICRO, "DOWNLOAD MICROCODE" }, 222162306a36Sopenharmony_ci { ATA_CMD_DOWNLOAD_MICRO_DMA, "DOWNLOAD MICROCODE DMA" }, 222262306a36Sopenharmony_ci { ATA_CMD_NOP, "NOP" }, 222362306a36Sopenharmony_ci { ATA_CMD_FLUSH, "FLUSH CACHE" }, 222462306a36Sopenharmony_ci { ATA_CMD_FLUSH_EXT, "FLUSH CACHE EXT" }, 222562306a36Sopenharmony_ci { ATA_CMD_ID_ATA, "IDENTIFY DEVICE" }, 222662306a36Sopenharmony_ci { ATA_CMD_ID_ATAPI, "IDENTIFY PACKET DEVICE" }, 222762306a36Sopenharmony_ci { ATA_CMD_SERVICE, "SERVICE" }, 222862306a36Sopenharmony_ci { ATA_CMD_READ, "READ DMA" }, 222962306a36Sopenharmony_ci { ATA_CMD_READ_EXT, "READ DMA EXT" }, 223062306a36Sopenharmony_ci { ATA_CMD_READ_QUEUED, "READ DMA QUEUED" }, 223162306a36Sopenharmony_ci { ATA_CMD_READ_STREAM_EXT, "READ STREAM EXT" }, 223262306a36Sopenharmony_ci { ATA_CMD_READ_STREAM_DMA_EXT, "READ STREAM DMA EXT" }, 223362306a36Sopenharmony_ci { ATA_CMD_WRITE, "WRITE DMA" }, 223462306a36Sopenharmony_ci { ATA_CMD_WRITE_EXT, "WRITE DMA EXT" }, 223562306a36Sopenharmony_ci { ATA_CMD_WRITE_QUEUED, "WRITE DMA QUEUED EXT" }, 223662306a36Sopenharmony_ci { ATA_CMD_WRITE_STREAM_EXT, "WRITE STREAM EXT" }, 223762306a36Sopenharmony_ci { ATA_CMD_WRITE_STREAM_DMA_EXT, "WRITE STREAM DMA EXT" }, 223862306a36Sopenharmony_ci { ATA_CMD_WRITE_FUA_EXT, "WRITE DMA FUA EXT" }, 223962306a36Sopenharmony_ci { ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" }, 224062306a36Sopenharmony_ci { ATA_CMD_FPDMA_READ, "READ FPDMA QUEUED" }, 224162306a36Sopenharmony_ci { ATA_CMD_FPDMA_WRITE, "WRITE FPDMA QUEUED" }, 224262306a36Sopenharmony_ci { ATA_CMD_NCQ_NON_DATA, "NCQ NON-DATA" }, 224362306a36Sopenharmony_ci { ATA_CMD_FPDMA_SEND, "SEND FPDMA QUEUED" }, 224462306a36Sopenharmony_ci { ATA_CMD_FPDMA_RECV, "RECEIVE FPDMA QUEUED" }, 224562306a36Sopenharmony_ci { ATA_CMD_PIO_READ, "READ SECTOR(S)" }, 224662306a36Sopenharmony_ci { ATA_CMD_PIO_READ_EXT, "READ SECTOR(S) EXT" }, 224762306a36Sopenharmony_ci { ATA_CMD_PIO_WRITE, "WRITE SECTOR(S)" }, 224862306a36Sopenharmony_ci { ATA_CMD_PIO_WRITE_EXT, "WRITE SECTOR(S) EXT" }, 224962306a36Sopenharmony_ci { ATA_CMD_READ_MULTI, "READ MULTIPLE" }, 225062306a36Sopenharmony_ci { ATA_CMD_READ_MULTI_EXT, "READ MULTIPLE EXT" }, 225162306a36Sopenharmony_ci { ATA_CMD_WRITE_MULTI, "WRITE MULTIPLE" }, 225262306a36Sopenharmony_ci { ATA_CMD_WRITE_MULTI_EXT, "WRITE MULTIPLE EXT" }, 225362306a36Sopenharmony_ci { ATA_CMD_WRITE_MULTI_FUA_EXT, "WRITE MULTIPLE FUA EXT" }, 225462306a36Sopenharmony_ci { ATA_CMD_SET_FEATURES, "SET FEATURES" }, 225562306a36Sopenharmony_ci { ATA_CMD_SET_MULTI, "SET MULTIPLE MODE" }, 225662306a36Sopenharmony_ci { ATA_CMD_VERIFY, "READ VERIFY SECTOR(S)" }, 225762306a36Sopenharmony_ci { ATA_CMD_VERIFY_EXT, "READ VERIFY SECTOR(S) EXT" }, 225862306a36Sopenharmony_ci { ATA_CMD_WRITE_UNCORR_EXT, "WRITE UNCORRECTABLE EXT" }, 225962306a36Sopenharmony_ci { ATA_CMD_STANDBYNOW1, "STANDBY IMMEDIATE" }, 226062306a36Sopenharmony_ci { ATA_CMD_IDLEIMMEDIATE, "IDLE IMMEDIATE" }, 226162306a36Sopenharmony_ci { ATA_CMD_SLEEP, "SLEEP" }, 226262306a36Sopenharmony_ci { ATA_CMD_INIT_DEV_PARAMS, "INITIALIZE DEVICE PARAMETERS" }, 226362306a36Sopenharmony_ci { ATA_CMD_READ_NATIVE_MAX, "READ NATIVE MAX ADDRESS" }, 226462306a36Sopenharmony_ci { ATA_CMD_READ_NATIVE_MAX_EXT, "READ NATIVE MAX ADDRESS EXT" }, 226562306a36Sopenharmony_ci { ATA_CMD_SET_MAX, "SET MAX ADDRESS" }, 226662306a36Sopenharmony_ci { ATA_CMD_SET_MAX_EXT, "SET MAX ADDRESS EXT" }, 226762306a36Sopenharmony_ci { ATA_CMD_READ_LOG_EXT, "READ LOG EXT" }, 226862306a36Sopenharmony_ci { ATA_CMD_WRITE_LOG_EXT, "WRITE LOG EXT" }, 226962306a36Sopenharmony_ci { ATA_CMD_READ_LOG_DMA_EXT, "READ LOG DMA EXT" }, 227062306a36Sopenharmony_ci { ATA_CMD_WRITE_LOG_DMA_EXT, "WRITE LOG DMA EXT" }, 227162306a36Sopenharmony_ci { ATA_CMD_TRUSTED_NONDATA, "TRUSTED NON-DATA" }, 227262306a36Sopenharmony_ci { ATA_CMD_TRUSTED_RCV, "TRUSTED RECEIVE" }, 227362306a36Sopenharmony_ci { ATA_CMD_TRUSTED_RCV_DMA, "TRUSTED RECEIVE DMA" }, 227462306a36Sopenharmony_ci { ATA_CMD_TRUSTED_SND, "TRUSTED SEND" }, 227562306a36Sopenharmony_ci { ATA_CMD_TRUSTED_SND_DMA, "TRUSTED SEND DMA" }, 227662306a36Sopenharmony_ci { ATA_CMD_PMP_READ, "READ BUFFER" }, 227762306a36Sopenharmony_ci { ATA_CMD_PMP_READ_DMA, "READ BUFFER DMA" }, 227862306a36Sopenharmony_ci { ATA_CMD_PMP_WRITE, "WRITE BUFFER" }, 227962306a36Sopenharmony_ci { ATA_CMD_PMP_WRITE_DMA, "WRITE BUFFER DMA" }, 228062306a36Sopenharmony_ci { ATA_CMD_CONF_OVERLAY, "DEVICE CONFIGURATION OVERLAY" }, 228162306a36Sopenharmony_ci { ATA_CMD_SEC_SET_PASS, "SECURITY SET PASSWORD" }, 228262306a36Sopenharmony_ci { ATA_CMD_SEC_UNLOCK, "SECURITY UNLOCK" }, 228362306a36Sopenharmony_ci { ATA_CMD_SEC_ERASE_PREP, "SECURITY ERASE PREPARE" }, 228462306a36Sopenharmony_ci { ATA_CMD_SEC_ERASE_UNIT, "SECURITY ERASE UNIT" }, 228562306a36Sopenharmony_ci { ATA_CMD_SEC_FREEZE_LOCK, "SECURITY FREEZE LOCK" }, 228662306a36Sopenharmony_ci { ATA_CMD_SEC_DISABLE_PASS, "SECURITY DISABLE PASSWORD" }, 228762306a36Sopenharmony_ci { ATA_CMD_CONFIG_STREAM, "CONFIGURE STREAM" }, 228862306a36Sopenharmony_ci { ATA_CMD_SMART, "SMART" }, 228962306a36Sopenharmony_ci { ATA_CMD_MEDIA_LOCK, "DOOR LOCK" }, 229062306a36Sopenharmony_ci { ATA_CMD_MEDIA_UNLOCK, "DOOR UNLOCK" }, 229162306a36Sopenharmony_ci { ATA_CMD_DSM, "DATA SET MANAGEMENT" }, 229262306a36Sopenharmony_ci { ATA_CMD_CHK_MED_CRD_TYP, "CHECK MEDIA CARD TYPE" }, 229362306a36Sopenharmony_ci { ATA_CMD_CFA_REQ_EXT_ERR, "CFA REQUEST EXTENDED ERROR" }, 229462306a36Sopenharmony_ci { ATA_CMD_CFA_WRITE_NE, "CFA WRITE SECTORS WITHOUT ERASE" }, 229562306a36Sopenharmony_ci { ATA_CMD_CFA_TRANS_SECT, "CFA TRANSLATE SECTOR" }, 229662306a36Sopenharmony_ci { ATA_CMD_CFA_ERASE, "CFA ERASE SECTORS" }, 229762306a36Sopenharmony_ci { ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" }, 229862306a36Sopenharmony_ci { ATA_CMD_REQ_SENSE_DATA, "REQUEST SENSE DATA EXT" }, 229962306a36Sopenharmony_ci { ATA_CMD_SANITIZE_DEVICE, "SANITIZE DEVICE" }, 230062306a36Sopenharmony_ci { ATA_CMD_ZAC_MGMT_IN, "ZAC MANAGEMENT IN" }, 230162306a36Sopenharmony_ci { ATA_CMD_ZAC_MGMT_OUT, "ZAC MANAGEMENT OUT" }, 230262306a36Sopenharmony_ci { ATA_CMD_READ_LONG, "READ LONG (with retries)" }, 230362306a36Sopenharmony_ci { ATA_CMD_READ_LONG_ONCE, "READ LONG (without retries)" }, 230462306a36Sopenharmony_ci { ATA_CMD_WRITE_LONG, "WRITE LONG (with retries)" }, 230562306a36Sopenharmony_ci { ATA_CMD_WRITE_LONG_ONCE, "WRITE LONG (without retries)" }, 230662306a36Sopenharmony_ci { ATA_CMD_RESTORE, "RECALIBRATE" }, 230762306a36Sopenharmony_ci { 0, NULL } /* terminate list */ 230862306a36Sopenharmony_ci }; 230962306a36Sopenharmony_ci 231062306a36Sopenharmony_ci unsigned int i; 231162306a36Sopenharmony_ci for (i = 0; cmd_descr[i].text; i++) 231262306a36Sopenharmony_ci if (cmd_descr[i].command == command) 231362306a36Sopenharmony_ci return cmd_descr[i].text; 231462306a36Sopenharmony_ci#endif 231562306a36Sopenharmony_ci 231662306a36Sopenharmony_ci return "unknown"; 231762306a36Sopenharmony_ci} 231862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_get_cmd_name); 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci/** 232162306a36Sopenharmony_ci * ata_eh_link_report - report error handling to user 232262306a36Sopenharmony_ci * @link: ATA link EH is going on 232362306a36Sopenharmony_ci * 232462306a36Sopenharmony_ci * Report EH to user. 232562306a36Sopenharmony_ci * 232662306a36Sopenharmony_ci * LOCKING: 232762306a36Sopenharmony_ci * None. 232862306a36Sopenharmony_ci */ 232962306a36Sopenharmony_cistatic void ata_eh_link_report(struct ata_link *link) 233062306a36Sopenharmony_ci{ 233162306a36Sopenharmony_ci struct ata_port *ap = link->ap; 233262306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 233362306a36Sopenharmony_ci struct ata_queued_cmd *qc; 233462306a36Sopenharmony_ci const char *frozen, *desc; 233562306a36Sopenharmony_ci char tries_buf[16] = ""; 233662306a36Sopenharmony_ci int tag, nr_failed = 0; 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_QUIET) 233962306a36Sopenharmony_ci return; 234062306a36Sopenharmony_ci 234162306a36Sopenharmony_ci desc = NULL; 234262306a36Sopenharmony_ci if (ehc->i.desc[0] != '\0') 234362306a36Sopenharmony_ci desc = ehc->i.desc; 234462306a36Sopenharmony_ci 234562306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, tag) { 234662306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH) || 234762306a36Sopenharmony_ci ata_dev_phys_link(qc->dev) != link || 234862306a36Sopenharmony_ci ((qc->flags & ATA_QCFLAG_QUIET) && 234962306a36Sopenharmony_ci qc->err_mask == AC_ERR_DEV)) 235062306a36Sopenharmony_ci continue; 235162306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_SENSE_VALID && !qc->err_mask) 235262306a36Sopenharmony_ci continue; 235362306a36Sopenharmony_ci 235462306a36Sopenharmony_ci nr_failed++; 235562306a36Sopenharmony_ci } 235662306a36Sopenharmony_ci 235762306a36Sopenharmony_ci if (!nr_failed && !ehc->i.err_mask) 235862306a36Sopenharmony_ci return; 235962306a36Sopenharmony_ci 236062306a36Sopenharmony_ci frozen = ""; 236162306a36Sopenharmony_ci if (ata_port_is_frozen(ap)) 236262306a36Sopenharmony_ci frozen = " frozen"; 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci if (ap->eh_tries < ATA_EH_MAX_TRIES) 236562306a36Sopenharmony_ci snprintf(tries_buf, sizeof(tries_buf), " t%d", 236662306a36Sopenharmony_ci ap->eh_tries); 236762306a36Sopenharmony_ci 236862306a36Sopenharmony_ci if (ehc->i.dev) { 236962306a36Sopenharmony_ci ata_dev_err(ehc->i.dev, "exception Emask 0x%x " 237062306a36Sopenharmony_ci "SAct 0x%x SErr 0x%x action 0x%x%s%s\n", 237162306a36Sopenharmony_ci ehc->i.err_mask, link->sactive, ehc->i.serror, 237262306a36Sopenharmony_ci ehc->i.action, frozen, tries_buf); 237362306a36Sopenharmony_ci if (desc) 237462306a36Sopenharmony_ci ata_dev_err(ehc->i.dev, "%s\n", desc); 237562306a36Sopenharmony_ci } else { 237662306a36Sopenharmony_ci ata_link_err(link, "exception Emask 0x%x " 237762306a36Sopenharmony_ci "SAct 0x%x SErr 0x%x action 0x%x%s%s\n", 237862306a36Sopenharmony_ci ehc->i.err_mask, link->sactive, ehc->i.serror, 237962306a36Sopenharmony_ci ehc->i.action, frozen, tries_buf); 238062306a36Sopenharmony_ci if (desc) 238162306a36Sopenharmony_ci ata_link_err(link, "%s\n", desc); 238262306a36Sopenharmony_ci } 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci#ifdef CONFIG_ATA_VERBOSE_ERROR 238562306a36Sopenharmony_ci if (ehc->i.serror) 238662306a36Sopenharmony_ci ata_link_err(link, 238762306a36Sopenharmony_ci "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n", 238862306a36Sopenharmony_ci ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "", 238962306a36Sopenharmony_ci ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "", 239062306a36Sopenharmony_ci ehc->i.serror & SERR_DATA ? "UnrecovData " : "", 239162306a36Sopenharmony_ci ehc->i.serror & SERR_PERSISTENT ? "Persist " : "", 239262306a36Sopenharmony_ci ehc->i.serror & SERR_PROTOCOL ? "Proto " : "", 239362306a36Sopenharmony_ci ehc->i.serror & SERR_INTERNAL ? "HostInt " : "", 239462306a36Sopenharmony_ci ehc->i.serror & SERR_PHYRDY_CHG ? "PHYRdyChg " : "", 239562306a36Sopenharmony_ci ehc->i.serror & SERR_PHY_INT_ERR ? "PHYInt " : "", 239662306a36Sopenharmony_ci ehc->i.serror & SERR_COMM_WAKE ? "CommWake " : "", 239762306a36Sopenharmony_ci ehc->i.serror & SERR_10B_8B_ERR ? "10B8B " : "", 239862306a36Sopenharmony_ci ehc->i.serror & SERR_DISPARITY ? "Dispar " : "", 239962306a36Sopenharmony_ci ehc->i.serror & SERR_CRC ? "BadCRC " : "", 240062306a36Sopenharmony_ci ehc->i.serror & SERR_HANDSHAKE ? "Handshk " : "", 240162306a36Sopenharmony_ci ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "", 240262306a36Sopenharmony_ci ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "", 240362306a36Sopenharmony_ci ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "", 240462306a36Sopenharmony_ci ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : ""); 240562306a36Sopenharmony_ci#endif 240662306a36Sopenharmony_ci 240762306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, tag) { 240862306a36Sopenharmony_ci struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf; 240962306a36Sopenharmony_ci char data_buf[20] = ""; 241062306a36Sopenharmony_ci char cdb_buf[70] = ""; 241162306a36Sopenharmony_ci 241262306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH) || 241362306a36Sopenharmony_ci ata_dev_phys_link(qc->dev) != link || !qc->err_mask) 241462306a36Sopenharmony_ci continue; 241562306a36Sopenharmony_ci 241662306a36Sopenharmony_ci if (qc->dma_dir != DMA_NONE) { 241762306a36Sopenharmony_ci static const char *dma_str[] = { 241862306a36Sopenharmony_ci [DMA_BIDIRECTIONAL] = "bidi", 241962306a36Sopenharmony_ci [DMA_TO_DEVICE] = "out", 242062306a36Sopenharmony_ci [DMA_FROM_DEVICE] = "in", 242162306a36Sopenharmony_ci }; 242262306a36Sopenharmony_ci const char *prot_str = NULL; 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_ci switch (qc->tf.protocol) { 242562306a36Sopenharmony_ci case ATA_PROT_UNKNOWN: 242662306a36Sopenharmony_ci prot_str = "unknown"; 242762306a36Sopenharmony_ci break; 242862306a36Sopenharmony_ci case ATA_PROT_NODATA: 242962306a36Sopenharmony_ci prot_str = "nodata"; 243062306a36Sopenharmony_ci break; 243162306a36Sopenharmony_ci case ATA_PROT_PIO: 243262306a36Sopenharmony_ci prot_str = "pio"; 243362306a36Sopenharmony_ci break; 243462306a36Sopenharmony_ci case ATA_PROT_DMA: 243562306a36Sopenharmony_ci prot_str = "dma"; 243662306a36Sopenharmony_ci break; 243762306a36Sopenharmony_ci case ATA_PROT_NCQ: 243862306a36Sopenharmony_ci prot_str = "ncq dma"; 243962306a36Sopenharmony_ci break; 244062306a36Sopenharmony_ci case ATA_PROT_NCQ_NODATA: 244162306a36Sopenharmony_ci prot_str = "ncq nodata"; 244262306a36Sopenharmony_ci break; 244362306a36Sopenharmony_ci case ATAPI_PROT_NODATA: 244462306a36Sopenharmony_ci prot_str = "nodata"; 244562306a36Sopenharmony_ci break; 244662306a36Sopenharmony_ci case ATAPI_PROT_PIO: 244762306a36Sopenharmony_ci prot_str = "pio"; 244862306a36Sopenharmony_ci break; 244962306a36Sopenharmony_ci case ATAPI_PROT_DMA: 245062306a36Sopenharmony_ci prot_str = "dma"; 245162306a36Sopenharmony_ci break; 245262306a36Sopenharmony_ci } 245362306a36Sopenharmony_ci snprintf(data_buf, sizeof(data_buf), " %s %u %s", 245462306a36Sopenharmony_ci prot_str, qc->nbytes, dma_str[qc->dma_dir]); 245562306a36Sopenharmony_ci } 245662306a36Sopenharmony_ci 245762306a36Sopenharmony_ci if (ata_is_atapi(qc->tf.protocol)) { 245862306a36Sopenharmony_ci const u8 *cdb = qc->cdb; 245962306a36Sopenharmony_ci size_t cdb_len = qc->dev->cdb_len; 246062306a36Sopenharmony_ci 246162306a36Sopenharmony_ci if (qc->scsicmd) { 246262306a36Sopenharmony_ci cdb = qc->scsicmd->cmnd; 246362306a36Sopenharmony_ci cdb_len = qc->scsicmd->cmd_len; 246462306a36Sopenharmony_ci } 246562306a36Sopenharmony_ci __scsi_format_command(cdb_buf, sizeof(cdb_buf), 246662306a36Sopenharmony_ci cdb, cdb_len); 246762306a36Sopenharmony_ci } else 246862306a36Sopenharmony_ci ata_dev_err(qc->dev, "failed command: %s\n", 246962306a36Sopenharmony_ci ata_get_cmd_name(cmd->command)); 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ci ata_dev_err(qc->dev, 247262306a36Sopenharmony_ci "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " 247362306a36Sopenharmony_ci "tag %d%s\n %s" 247462306a36Sopenharmony_ci "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " 247562306a36Sopenharmony_ci "Emask 0x%x (%s)%s\n", 247662306a36Sopenharmony_ci cmd->command, cmd->feature, cmd->nsect, 247762306a36Sopenharmony_ci cmd->lbal, cmd->lbam, cmd->lbah, 247862306a36Sopenharmony_ci cmd->hob_feature, cmd->hob_nsect, 247962306a36Sopenharmony_ci cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah, 248062306a36Sopenharmony_ci cmd->device, qc->tag, data_buf, cdb_buf, 248162306a36Sopenharmony_ci res->status, res->error, res->nsect, 248262306a36Sopenharmony_ci res->lbal, res->lbam, res->lbah, 248362306a36Sopenharmony_ci res->hob_feature, res->hob_nsect, 248462306a36Sopenharmony_ci res->hob_lbal, res->hob_lbam, res->hob_lbah, 248562306a36Sopenharmony_ci res->device, qc->err_mask, ata_err_string(qc->err_mask), 248662306a36Sopenharmony_ci qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); 248762306a36Sopenharmony_ci 248862306a36Sopenharmony_ci#ifdef CONFIG_ATA_VERBOSE_ERROR 248962306a36Sopenharmony_ci if (res->status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | 249062306a36Sopenharmony_ci ATA_SENSE | ATA_ERR)) { 249162306a36Sopenharmony_ci if (res->status & ATA_BUSY) 249262306a36Sopenharmony_ci ata_dev_err(qc->dev, "status: { Busy }\n"); 249362306a36Sopenharmony_ci else 249462306a36Sopenharmony_ci ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n", 249562306a36Sopenharmony_ci res->status & ATA_DRDY ? "DRDY " : "", 249662306a36Sopenharmony_ci res->status & ATA_DF ? "DF " : "", 249762306a36Sopenharmony_ci res->status & ATA_DRQ ? "DRQ " : "", 249862306a36Sopenharmony_ci res->status & ATA_SENSE ? "SENSE " : "", 249962306a36Sopenharmony_ci res->status & ATA_ERR ? "ERR " : ""); 250062306a36Sopenharmony_ci } 250162306a36Sopenharmony_ci 250262306a36Sopenharmony_ci if (cmd->command != ATA_CMD_PACKET && 250362306a36Sopenharmony_ci (res->error & (ATA_ICRC | ATA_UNC | ATA_AMNF | ATA_IDNF | 250462306a36Sopenharmony_ci ATA_ABORTED))) 250562306a36Sopenharmony_ci ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n", 250662306a36Sopenharmony_ci res->error & ATA_ICRC ? "ICRC " : "", 250762306a36Sopenharmony_ci res->error & ATA_UNC ? "UNC " : "", 250862306a36Sopenharmony_ci res->error & ATA_AMNF ? "AMNF " : "", 250962306a36Sopenharmony_ci res->error & ATA_IDNF ? "IDNF " : "", 251062306a36Sopenharmony_ci res->error & ATA_ABORTED ? "ABRT " : ""); 251162306a36Sopenharmony_ci#endif 251262306a36Sopenharmony_ci } 251362306a36Sopenharmony_ci} 251462306a36Sopenharmony_ci 251562306a36Sopenharmony_ci/** 251662306a36Sopenharmony_ci * ata_eh_report - report error handling to user 251762306a36Sopenharmony_ci * @ap: ATA port to report EH about 251862306a36Sopenharmony_ci * 251962306a36Sopenharmony_ci * Report EH to user. 252062306a36Sopenharmony_ci * 252162306a36Sopenharmony_ci * LOCKING: 252262306a36Sopenharmony_ci * None. 252362306a36Sopenharmony_ci */ 252462306a36Sopenharmony_civoid ata_eh_report(struct ata_port *ap) 252562306a36Sopenharmony_ci{ 252662306a36Sopenharmony_ci struct ata_link *link; 252762306a36Sopenharmony_ci 252862306a36Sopenharmony_ci ata_for_each_link(link, ap, HOST_FIRST) 252962306a36Sopenharmony_ci ata_eh_link_report(link); 253062306a36Sopenharmony_ci} 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_cistatic int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, 253362306a36Sopenharmony_ci unsigned int *classes, unsigned long deadline, 253462306a36Sopenharmony_ci bool clear_classes) 253562306a36Sopenharmony_ci{ 253662306a36Sopenharmony_ci struct ata_device *dev; 253762306a36Sopenharmony_ci 253862306a36Sopenharmony_ci if (clear_classes) 253962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 254062306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_UNKNOWN; 254162306a36Sopenharmony_ci 254262306a36Sopenharmony_ci return reset(link, classes, deadline); 254362306a36Sopenharmony_ci} 254462306a36Sopenharmony_ci 254562306a36Sopenharmony_cistatic int ata_eh_followup_srst_needed(struct ata_link *link, int rc) 254662306a36Sopenharmony_ci{ 254762306a36Sopenharmony_ci if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link)) 254862306a36Sopenharmony_ci return 0; 254962306a36Sopenharmony_ci if (rc == -EAGAIN) 255062306a36Sopenharmony_ci return 1; 255162306a36Sopenharmony_ci if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) 255262306a36Sopenharmony_ci return 1; 255362306a36Sopenharmony_ci return 0; 255462306a36Sopenharmony_ci} 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ciint ata_eh_reset(struct ata_link *link, int classify, 255762306a36Sopenharmony_ci ata_prereset_fn_t prereset, ata_reset_fn_t softreset, 255862306a36Sopenharmony_ci ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) 255962306a36Sopenharmony_ci{ 256062306a36Sopenharmony_ci struct ata_port *ap = link->ap; 256162306a36Sopenharmony_ci struct ata_link *slave = ap->slave_link; 256262306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 256362306a36Sopenharmony_ci struct ata_eh_context *sehc = slave ? &slave->eh_context : NULL; 256462306a36Sopenharmony_ci unsigned int *classes = ehc->classes; 256562306a36Sopenharmony_ci unsigned int lflags = link->flags; 256662306a36Sopenharmony_ci int verbose = !(ehc->i.flags & ATA_EHI_QUIET); 256762306a36Sopenharmony_ci int max_tries = 0, try = 0; 256862306a36Sopenharmony_ci struct ata_link *failed_link; 256962306a36Sopenharmony_ci struct ata_device *dev; 257062306a36Sopenharmony_ci unsigned long deadline, now; 257162306a36Sopenharmony_ci ata_reset_fn_t reset; 257262306a36Sopenharmony_ci unsigned long flags; 257362306a36Sopenharmony_ci u32 sstatus; 257462306a36Sopenharmony_ci int nr_unknown, rc; 257562306a36Sopenharmony_ci 257662306a36Sopenharmony_ci /* 257762306a36Sopenharmony_ci * Prepare to reset 257862306a36Sopenharmony_ci */ 257962306a36Sopenharmony_ci while (ata_eh_reset_timeouts[max_tries] != UINT_MAX) 258062306a36Sopenharmony_ci max_tries++; 258162306a36Sopenharmony_ci if (link->flags & ATA_LFLAG_RST_ONCE) 258262306a36Sopenharmony_ci max_tries = 1; 258362306a36Sopenharmony_ci if (link->flags & ATA_LFLAG_NO_HRST) 258462306a36Sopenharmony_ci hardreset = NULL; 258562306a36Sopenharmony_ci if (link->flags & ATA_LFLAG_NO_SRST) 258662306a36Sopenharmony_ci softreset = NULL; 258762306a36Sopenharmony_ci 258862306a36Sopenharmony_ci /* make sure each reset attempt is at least COOL_DOWN apart */ 258962306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_DID_RESET) { 259062306a36Sopenharmony_ci now = jiffies; 259162306a36Sopenharmony_ci WARN_ON(time_after(ehc->last_reset, now)); 259262306a36Sopenharmony_ci deadline = ata_deadline(ehc->last_reset, 259362306a36Sopenharmony_ci ATA_EH_RESET_COOL_DOWN); 259462306a36Sopenharmony_ci if (time_before(now, deadline)) 259562306a36Sopenharmony_ci schedule_timeout_uninterruptible(deadline - now); 259662306a36Sopenharmony_ci } 259762306a36Sopenharmony_ci 259862306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 259962306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_RESETTING; 260062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 260162306a36Sopenharmony_ci 260262306a36Sopenharmony_ci ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 260362306a36Sopenharmony_ci 260462306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 260562306a36Sopenharmony_ci /* If we issue an SRST then an ATA drive (not ATAPI) 260662306a36Sopenharmony_ci * may change configuration and be in PIO0 timing. If 260762306a36Sopenharmony_ci * we do a hard reset (or are coming from power on) 260862306a36Sopenharmony_ci * this is true for ATA or ATAPI. Until we've set a 260962306a36Sopenharmony_ci * suitable controller mode we should not touch the 261062306a36Sopenharmony_ci * bus as we may be talking too fast. 261162306a36Sopenharmony_ci */ 261262306a36Sopenharmony_ci dev->pio_mode = XFER_PIO_0; 261362306a36Sopenharmony_ci dev->dma_mode = 0xff; 261462306a36Sopenharmony_ci 261562306a36Sopenharmony_ci /* If the controller has a pio mode setup function 261662306a36Sopenharmony_ci * then use it to set the chipset to rights. Don't 261762306a36Sopenharmony_ci * touch the DMA setup as that will be dealt with when 261862306a36Sopenharmony_ci * configuring devices. 261962306a36Sopenharmony_ci */ 262062306a36Sopenharmony_ci if (ap->ops->set_piomode) 262162306a36Sopenharmony_ci ap->ops->set_piomode(ap, dev); 262262306a36Sopenharmony_ci } 262362306a36Sopenharmony_ci 262462306a36Sopenharmony_ci /* prefer hardreset */ 262562306a36Sopenharmony_ci reset = NULL; 262662306a36Sopenharmony_ci ehc->i.action &= ~ATA_EH_RESET; 262762306a36Sopenharmony_ci if (hardreset) { 262862306a36Sopenharmony_ci reset = hardreset; 262962306a36Sopenharmony_ci ehc->i.action |= ATA_EH_HARDRESET; 263062306a36Sopenharmony_ci } else if (softreset) { 263162306a36Sopenharmony_ci reset = softreset; 263262306a36Sopenharmony_ci ehc->i.action |= ATA_EH_SOFTRESET; 263362306a36Sopenharmony_ci } 263462306a36Sopenharmony_ci 263562306a36Sopenharmony_ci if (prereset) { 263662306a36Sopenharmony_ci unsigned long deadline = ata_deadline(jiffies, 263762306a36Sopenharmony_ci ATA_EH_PRERESET_TIMEOUT); 263862306a36Sopenharmony_ci 263962306a36Sopenharmony_ci if (slave) { 264062306a36Sopenharmony_ci sehc->i.action &= ~ATA_EH_RESET; 264162306a36Sopenharmony_ci sehc->i.action |= ehc->i.action; 264262306a36Sopenharmony_ci } 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci rc = prereset(link, deadline); 264562306a36Sopenharmony_ci 264662306a36Sopenharmony_ci /* If present, do prereset on slave link too. Reset 264762306a36Sopenharmony_ci * is skipped iff both master and slave links report 264862306a36Sopenharmony_ci * -ENOENT or clear ATA_EH_RESET. 264962306a36Sopenharmony_ci */ 265062306a36Sopenharmony_ci if (slave && (rc == 0 || rc == -ENOENT)) { 265162306a36Sopenharmony_ci int tmp; 265262306a36Sopenharmony_ci 265362306a36Sopenharmony_ci tmp = prereset(slave, deadline); 265462306a36Sopenharmony_ci if (tmp != -ENOENT) 265562306a36Sopenharmony_ci rc = tmp; 265662306a36Sopenharmony_ci 265762306a36Sopenharmony_ci ehc->i.action |= sehc->i.action; 265862306a36Sopenharmony_ci } 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci if (rc) { 266162306a36Sopenharmony_ci if (rc == -ENOENT) { 266262306a36Sopenharmony_ci ata_link_dbg(link, "port disabled--ignoring\n"); 266362306a36Sopenharmony_ci ehc->i.action &= ~ATA_EH_RESET; 266462306a36Sopenharmony_ci 266562306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 266662306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_NONE; 266762306a36Sopenharmony_ci 266862306a36Sopenharmony_ci rc = 0; 266962306a36Sopenharmony_ci } else 267062306a36Sopenharmony_ci ata_link_err(link, 267162306a36Sopenharmony_ci "prereset failed (errno=%d)\n", 267262306a36Sopenharmony_ci rc); 267362306a36Sopenharmony_ci goto out; 267462306a36Sopenharmony_ci } 267562306a36Sopenharmony_ci 267662306a36Sopenharmony_ci /* prereset() might have cleared ATA_EH_RESET. If so, 267762306a36Sopenharmony_ci * bang classes, thaw and return. 267862306a36Sopenharmony_ci */ 267962306a36Sopenharmony_ci if (reset && !(ehc->i.action & ATA_EH_RESET)) { 268062306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 268162306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_NONE; 268262306a36Sopenharmony_ci if (ata_port_is_frozen(ap) && ata_is_host_link(link)) 268362306a36Sopenharmony_ci ata_eh_thaw_port(ap); 268462306a36Sopenharmony_ci rc = 0; 268562306a36Sopenharmony_ci goto out; 268662306a36Sopenharmony_ci } 268762306a36Sopenharmony_ci } 268862306a36Sopenharmony_ci 268962306a36Sopenharmony_ci retry: 269062306a36Sopenharmony_ci /* 269162306a36Sopenharmony_ci * Perform reset 269262306a36Sopenharmony_ci */ 269362306a36Sopenharmony_ci if (ata_is_host_link(link)) 269462306a36Sopenharmony_ci ata_eh_freeze_port(ap); 269562306a36Sopenharmony_ci 269662306a36Sopenharmony_ci deadline = ata_deadline(jiffies, ata_eh_reset_timeouts[try++]); 269762306a36Sopenharmony_ci 269862306a36Sopenharmony_ci if (reset) { 269962306a36Sopenharmony_ci if (verbose) 270062306a36Sopenharmony_ci ata_link_info(link, "%s resetting link\n", 270162306a36Sopenharmony_ci reset == softreset ? "soft" : "hard"); 270262306a36Sopenharmony_ci 270362306a36Sopenharmony_ci /* mark that this EH session started with reset */ 270462306a36Sopenharmony_ci ehc->last_reset = jiffies; 270562306a36Sopenharmony_ci if (reset == hardreset) { 270662306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_DID_HARDRESET; 270762306a36Sopenharmony_ci trace_ata_link_hardreset_begin(link, classes, deadline); 270862306a36Sopenharmony_ci } else { 270962306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_DID_SOFTRESET; 271062306a36Sopenharmony_ci trace_ata_link_softreset_begin(link, classes, deadline); 271162306a36Sopenharmony_ci } 271262306a36Sopenharmony_ci 271362306a36Sopenharmony_ci rc = ata_do_reset(link, reset, classes, deadline, true); 271462306a36Sopenharmony_ci if (reset == hardreset) 271562306a36Sopenharmony_ci trace_ata_link_hardreset_end(link, classes, rc); 271662306a36Sopenharmony_ci else 271762306a36Sopenharmony_ci trace_ata_link_softreset_end(link, classes, rc); 271862306a36Sopenharmony_ci if (rc && rc != -EAGAIN) { 271962306a36Sopenharmony_ci failed_link = link; 272062306a36Sopenharmony_ci goto fail; 272162306a36Sopenharmony_ci } 272262306a36Sopenharmony_ci 272362306a36Sopenharmony_ci /* hardreset slave link if existent */ 272462306a36Sopenharmony_ci if (slave && reset == hardreset) { 272562306a36Sopenharmony_ci int tmp; 272662306a36Sopenharmony_ci 272762306a36Sopenharmony_ci if (verbose) 272862306a36Sopenharmony_ci ata_link_info(slave, "hard resetting link\n"); 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci ata_eh_about_to_do(slave, NULL, ATA_EH_RESET); 273162306a36Sopenharmony_ci trace_ata_slave_hardreset_begin(slave, classes, 273262306a36Sopenharmony_ci deadline); 273362306a36Sopenharmony_ci tmp = ata_do_reset(slave, reset, classes, deadline, 273462306a36Sopenharmony_ci false); 273562306a36Sopenharmony_ci trace_ata_slave_hardreset_end(slave, classes, tmp); 273662306a36Sopenharmony_ci switch (tmp) { 273762306a36Sopenharmony_ci case -EAGAIN: 273862306a36Sopenharmony_ci rc = -EAGAIN; 273962306a36Sopenharmony_ci break; 274062306a36Sopenharmony_ci case 0: 274162306a36Sopenharmony_ci break; 274262306a36Sopenharmony_ci default: 274362306a36Sopenharmony_ci failed_link = slave; 274462306a36Sopenharmony_ci rc = tmp; 274562306a36Sopenharmony_ci goto fail; 274662306a36Sopenharmony_ci } 274762306a36Sopenharmony_ci } 274862306a36Sopenharmony_ci 274962306a36Sopenharmony_ci /* perform follow-up SRST if necessary */ 275062306a36Sopenharmony_ci if (reset == hardreset && 275162306a36Sopenharmony_ci ata_eh_followup_srst_needed(link, rc)) { 275262306a36Sopenharmony_ci reset = softreset; 275362306a36Sopenharmony_ci 275462306a36Sopenharmony_ci if (!reset) { 275562306a36Sopenharmony_ci ata_link_err(link, 275662306a36Sopenharmony_ci "follow-up softreset required but no softreset available\n"); 275762306a36Sopenharmony_ci failed_link = link; 275862306a36Sopenharmony_ci rc = -EINVAL; 275962306a36Sopenharmony_ci goto fail; 276062306a36Sopenharmony_ci } 276162306a36Sopenharmony_ci 276262306a36Sopenharmony_ci ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 276362306a36Sopenharmony_ci trace_ata_link_softreset_begin(link, classes, deadline); 276462306a36Sopenharmony_ci rc = ata_do_reset(link, reset, classes, deadline, true); 276562306a36Sopenharmony_ci trace_ata_link_softreset_end(link, classes, rc); 276662306a36Sopenharmony_ci if (rc) { 276762306a36Sopenharmony_ci failed_link = link; 276862306a36Sopenharmony_ci goto fail; 276962306a36Sopenharmony_ci } 277062306a36Sopenharmony_ci } 277162306a36Sopenharmony_ci } else { 277262306a36Sopenharmony_ci if (verbose) 277362306a36Sopenharmony_ci ata_link_info(link, 277462306a36Sopenharmony_ci "no reset method available, skipping reset\n"); 277562306a36Sopenharmony_ci if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) 277662306a36Sopenharmony_ci lflags |= ATA_LFLAG_ASSUME_ATA; 277762306a36Sopenharmony_ci } 277862306a36Sopenharmony_ci 277962306a36Sopenharmony_ci /* 278062306a36Sopenharmony_ci * Post-reset processing 278162306a36Sopenharmony_ci */ 278262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 278362306a36Sopenharmony_ci /* After the reset, the device state is PIO 0 and the 278462306a36Sopenharmony_ci * controller state is undefined. Reset also wakes up 278562306a36Sopenharmony_ci * drives from sleeping mode. 278662306a36Sopenharmony_ci */ 278762306a36Sopenharmony_ci dev->pio_mode = XFER_PIO_0; 278862306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_SLEEPING; 278962306a36Sopenharmony_ci 279062306a36Sopenharmony_ci if (ata_phys_link_offline(ata_dev_phys_link(dev))) 279162306a36Sopenharmony_ci continue; 279262306a36Sopenharmony_ci 279362306a36Sopenharmony_ci /* apply class override */ 279462306a36Sopenharmony_ci if (lflags & ATA_LFLAG_ASSUME_ATA) 279562306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_ATA; 279662306a36Sopenharmony_ci else if (lflags & ATA_LFLAG_ASSUME_SEMB) 279762306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_SEMB_UNSUP; 279862306a36Sopenharmony_ci } 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci /* record current link speed */ 280162306a36Sopenharmony_ci if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) 280262306a36Sopenharmony_ci link->sata_spd = (sstatus >> 4) & 0xf; 280362306a36Sopenharmony_ci if (slave && sata_scr_read(slave, SCR_STATUS, &sstatus) == 0) 280462306a36Sopenharmony_ci slave->sata_spd = (sstatus >> 4) & 0xf; 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci /* thaw the port */ 280762306a36Sopenharmony_ci if (ata_is_host_link(link)) 280862306a36Sopenharmony_ci ata_eh_thaw_port(ap); 280962306a36Sopenharmony_ci 281062306a36Sopenharmony_ci /* postreset() should clear hardware SError. Although SError 281162306a36Sopenharmony_ci * is cleared during link resume, clearing SError here is 281262306a36Sopenharmony_ci * necessary as some PHYs raise hotplug events after SRST. 281362306a36Sopenharmony_ci * This introduces race condition where hotplug occurs between 281462306a36Sopenharmony_ci * reset and here. This race is mediated by cross checking 281562306a36Sopenharmony_ci * link onlineness and classification result later. 281662306a36Sopenharmony_ci */ 281762306a36Sopenharmony_ci if (postreset) { 281862306a36Sopenharmony_ci postreset(link, classes); 281962306a36Sopenharmony_ci trace_ata_link_postreset(link, classes, rc); 282062306a36Sopenharmony_ci if (slave) { 282162306a36Sopenharmony_ci postreset(slave, classes); 282262306a36Sopenharmony_ci trace_ata_slave_postreset(slave, classes, rc); 282362306a36Sopenharmony_ci } 282462306a36Sopenharmony_ci } 282562306a36Sopenharmony_ci 282662306a36Sopenharmony_ci /* clear cached SError */ 282762306a36Sopenharmony_ci spin_lock_irqsave(link->ap->lock, flags); 282862306a36Sopenharmony_ci link->eh_info.serror = 0; 282962306a36Sopenharmony_ci if (slave) 283062306a36Sopenharmony_ci slave->eh_info.serror = 0; 283162306a36Sopenharmony_ci spin_unlock_irqrestore(link->ap->lock, flags); 283262306a36Sopenharmony_ci 283362306a36Sopenharmony_ci /* 283462306a36Sopenharmony_ci * Make sure onlineness and classification result correspond. 283562306a36Sopenharmony_ci * Hotplug could have happened during reset and some 283662306a36Sopenharmony_ci * controllers fail to wait while a drive is spinning up after 283762306a36Sopenharmony_ci * being hotplugged causing misdetection. By cross checking 283862306a36Sopenharmony_ci * link on/offlineness and classification result, those 283962306a36Sopenharmony_ci * conditions can be reliably detected and retried. 284062306a36Sopenharmony_ci */ 284162306a36Sopenharmony_ci nr_unknown = 0; 284262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 284362306a36Sopenharmony_ci if (ata_phys_link_online(ata_dev_phys_link(dev))) { 284462306a36Sopenharmony_ci if (classes[dev->devno] == ATA_DEV_UNKNOWN) { 284562306a36Sopenharmony_ci ata_dev_dbg(dev, "link online but device misclassified\n"); 284662306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_NONE; 284762306a36Sopenharmony_ci nr_unknown++; 284862306a36Sopenharmony_ci } 284962306a36Sopenharmony_ci } else if (ata_phys_link_offline(ata_dev_phys_link(dev))) { 285062306a36Sopenharmony_ci if (ata_class_enabled(classes[dev->devno])) 285162306a36Sopenharmony_ci ata_dev_dbg(dev, 285262306a36Sopenharmony_ci "link offline, clearing class %d to NONE\n", 285362306a36Sopenharmony_ci classes[dev->devno]); 285462306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_NONE; 285562306a36Sopenharmony_ci } else if (classes[dev->devno] == ATA_DEV_UNKNOWN) { 285662306a36Sopenharmony_ci ata_dev_dbg(dev, 285762306a36Sopenharmony_ci "link status unknown, clearing UNKNOWN to NONE\n"); 285862306a36Sopenharmony_ci classes[dev->devno] = ATA_DEV_NONE; 285962306a36Sopenharmony_ci } 286062306a36Sopenharmony_ci } 286162306a36Sopenharmony_ci 286262306a36Sopenharmony_ci if (classify && nr_unknown) { 286362306a36Sopenharmony_ci if (try < max_tries) { 286462306a36Sopenharmony_ci ata_link_warn(link, 286562306a36Sopenharmony_ci "link online but %d devices misclassified, retrying\n", 286662306a36Sopenharmony_ci nr_unknown); 286762306a36Sopenharmony_ci failed_link = link; 286862306a36Sopenharmony_ci rc = -EAGAIN; 286962306a36Sopenharmony_ci goto fail; 287062306a36Sopenharmony_ci } 287162306a36Sopenharmony_ci ata_link_warn(link, 287262306a36Sopenharmony_ci "link online but %d devices misclassified, " 287362306a36Sopenharmony_ci "device detection might fail\n", nr_unknown); 287462306a36Sopenharmony_ci } 287562306a36Sopenharmony_ci 287662306a36Sopenharmony_ci /* reset successful, schedule revalidation */ 287762306a36Sopenharmony_ci ata_eh_done(link, NULL, ATA_EH_RESET); 287862306a36Sopenharmony_ci if (slave) 287962306a36Sopenharmony_ci ata_eh_done(slave, NULL, ATA_EH_RESET); 288062306a36Sopenharmony_ci ehc->last_reset = jiffies; /* update to completion time */ 288162306a36Sopenharmony_ci ehc->i.action |= ATA_EH_REVALIDATE; 288262306a36Sopenharmony_ci link->lpm_policy = ATA_LPM_UNKNOWN; /* reset LPM state */ 288362306a36Sopenharmony_ci 288462306a36Sopenharmony_ci rc = 0; 288562306a36Sopenharmony_ci out: 288662306a36Sopenharmony_ci /* clear hotplug flag */ 288762306a36Sopenharmony_ci ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; 288862306a36Sopenharmony_ci if (slave) 288962306a36Sopenharmony_ci sehc->i.flags &= ~ATA_EHI_HOTPLUGGED; 289062306a36Sopenharmony_ci 289162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 289262306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_RESETTING; 289362306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 289462306a36Sopenharmony_ci 289562306a36Sopenharmony_ci return rc; 289662306a36Sopenharmony_ci 289762306a36Sopenharmony_ci fail: 289862306a36Sopenharmony_ci /* if SCR isn't accessible on a fan-out port, PMP needs to be reset */ 289962306a36Sopenharmony_ci if (!ata_is_host_link(link) && 290062306a36Sopenharmony_ci sata_scr_read(link, SCR_STATUS, &sstatus)) 290162306a36Sopenharmony_ci rc = -ERESTART; 290262306a36Sopenharmony_ci 290362306a36Sopenharmony_ci if (try >= max_tries) { 290462306a36Sopenharmony_ci /* 290562306a36Sopenharmony_ci * Thaw host port even if reset failed, so that the port 290662306a36Sopenharmony_ci * can be retried on the next phy event. This risks 290762306a36Sopenharmony_ci * repeated EH runs but seems to be a better tradeoff than 290862306a36Sopenharmony_ci * shutting down a port after a botched hotplug attempt. 290962306a36Sopenharmony_ci */ 291062306a36Sopenharmony_ci if (ata_is_host_link(link)) 291162306a36Sopenharmony_ci ata_eh_thaw_port(ap); 291262306a36Sopenharmony_ci goto out; 291362306a36Sopenharmony_ci } 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci now = jiffies; 291662306a36Sopenharmony_ci if (time_before(now, deadline)) { 291762306a36Sopenharmony_ci unsigned long delta = deadline - now; 291862306a36Sopenharmony_ci 291962306a36Sopenharmony_ci ata_link_warn(failed_link, 292062306a36Sopenharmony_ci "reset failed (errno=%d), retrying in %u secs\n", 292162306a36Sopenharmony_ci rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); 292262306a36Sopenharmony_ci 292362306a36Sopenharmony_ci ata_eh_release(ap); 292462306a36Sopenharmony_ci while (delta) 292562306a36Sopenharmony_ci delta = schedule_timeout_uninterruptible(delta); 292662306a36Sopenharmony_ci ata_eh_acquire(ap); 292762306a36Sopenharmony_ci } 292862306a36Sopenharmony_ci 292962306a36Sopenharmony_ci /* 293062306a36Sopenharmony_ci * While disks spinup behind PMP, some controllers fail sending SRST. 293162306a36Sopenharmony_ci * They need to be reset - as well as the PMP - before retrying. 293262306a36Sopenharmony_ci */ 293362306a36Sopenharmony_ci if (rc == -ERESTART) { 293462306a36Sopenharmony_ci if (ata_is_host_link(link)) 293562306a36Sopenharmony_ci ata_eh_thaw_port(ap); 293662306a36Sopenharmony_ci goto out; 293762306a36Sopenharmony_ci } 293862306a36Sopenharmony_ci 293962306a36Sopenharmony_ci if (try == max_tries - 1) { 294062306a36Sopenharmony_ci sata_down_spd_limit(link, 0); 294162306a36Sopenharmony_ci if (slave) 294262306a36Sopenharmony_ci sata_down_spd_limit(slave, 0); 294362306a36Sopenharmony_ci } else if (rc == -EPIPE) 294462306a36Sopenharmony_ci sata_down_spd_limit(failed_link, 0); 294562306a36Sopenharmony_ci 294662306a36Sopenharmony_ci if (hardreset) 294762306a36Sopenharmony_ci reset = hardreset; 294862306a36Sopenharmony_ci goto retry; 294962306a36Sopenharmony_ci} 295062306a36Sopenharmony_ci 295162306a36Sopenharmony_cistatic inline void ata_eh_pull_park_action(struct ata_port *ap) 295262306a36Sopenharmony_ci{ 295362306a36Sopenharmony_ci struct ata_link *link; 295462306a36Sopenharmony_ci struct ata_device *dev; 295562306a36Sopenharmony_ci unsigned long flags; 295662306a36Sopenharmony_ci 295762306a36Sopenharmony_ci /* 295862306a36Sopenharmony_ci * This function can be thought of as an extended version of 295962306a36Sopenharmony_ci * ata_eh_about_to_do() specially crafted to accommodate the 296062306a36Sopenharmony_ci * requirements of ATA_EH_PARK handling. Since the EH thread 296162306a36Sopenharmony_ci * does not leave the do {} while () loop in ata_eh_recover as 296262306a36Sopenharmony_ci * long as the timeout for a park request to *one* device on 296362306a36Sopenharmony_ci * the port has not expired, and since we still want to pick 296462306a36Sopenharmony_ci * up park requests to other devices on the same port or 296562306a36Sopenharmony_ci * timeout updates for the same device, we have to pull 296662306a36Sopenharmony_ci * ATA_EH_PARK actions from eh_info into eh_context.i 296762306a36Sopenharmony_ci * ourselves at the beginning of each pass over the loop. 296862306a36Sopenharmony_ci * 296962306a36Sopenharmony_ci * Additionally, all write accesses to &ap->park_req_pending 297062306a36Sopenharmony_ci * through reinit_completion() (see below) or complete_all() 297162306a36Sopenharmony_ci * (see ata_scsi_park_store()) are protected by the host lock. 297262306a36Sopenharmony_ci * As a result we have that park_req_pending.done is zero on 297362306a36Sopenharmony_ci * exit from this function, i.e. when ATA_EH_PARK actions for 297462306a36Sopenharmony_ci * *all* devices on port ap have been pulled into the 297562306a36Sopenharmony_ci * respective eh_context structs. If, and only if, 297662306a36Sopenharmony_ci * park_req_pending.done is non-zero by the time we reach 297762306a36Sopenharmony_ci * wait_for_completion_timeout(), another ATA_EH_PARK action 297862306a36Sopenharmony_ci * has been scheduled for at least one of the devices on port 297962306a36Sopenharmony_ci * ap and we have to cycle over the do {} while () loop in 298062306a36Sopenharmony_ci * ata_eh_recover() again. 298162306a36Sopenharmony_ci */ 298262306a36Sopenharmony_ci 298362306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 298462306a36Sopenharmony_ci reinit_completion(&ap->park_req_pending); 298562306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 298662306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 298762306a36Sopenharmony_ci struct ata_eh_info *ehi = &link->eh_info; 298862306a36Sopenharmony_ci 298962306a36Sopenharmony_ci link->eh_context.i.dev_action[dev->devno] |= 299062306a36Sopenharmony_ci ehi->dev_action[dev->devno] & ATA_EH_PARK; 299162306a36Sopenharmony_ci ata_eh_clear_action(link, dev, ehi, ATA_EH_PARK); 299262306a36Sopenharmony_ci } 299362306a36Sopenharmony_ci } 299462306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 299562306a36Sopenharmony_ci} 299662306a36Sopenharmony_ci 299762306a36Sopenharmony_cistatic void ata_eh_park_issue_cmd(struct ata_device *dev, int park) 299862306a36Sopenharmony_ci{ 299962306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 300062306a36Sopenharmony_ci struct ata_taskfile tf; 300162306a36Sopenharmony_ci unsigned int err_mask; 300262306a36Sopenharmony_ci 300362306a36Sopenharmony_ci ata_tf_init(dev, &tf); 300462306a36Sopenharmony_ci if (park) { 300562306a36Sopenharmony_ci ehc->unloaded_mask |= 1 << dev->devno; 300662306a36Sopenharmony_ci tf.command = ATA_CMD_IDLEIMMEDIATE; 300762306a36Sopenharmony_ci tf.feature = 0x44; 300862306a36Sopenharmony_ci tf.lbal = 0x4c; 300962306a36Sopenharmony_ci tf.lbam = 0x4e; 301062306a36Sopenharmony_ci tf.lbah = 0x55; 301162306a36Sopenharmony_ci } else { 301262306a36Sopenharmony_ci ehc->unloaded_mask &= ~(1 << dev->devno); 301362306a36Sopenharmony_ci tf.command = ATA_CMD_CHK_POWER; 301462306a36Sopenharmony_ci } 301562306a36Sopenharmony_ci 301662306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 301762306a36Sopenharmony_ci tf.protocol = ATA_PROT_NODATA; 301862306a36Sopenharmony_ci err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); 301962306a36Sopenharmony_ci if (park && (err_mask || tf.lbal != 0xc4)) { 302062306a36Sopenharmony_ci ata_dev_err(dev, "head unload failed!\n"); 302162306a36Sopenharmony_ci ehc->unloaded_mask &= ~(1 << dev->devno); 302262306a36Sopenharmony_ci } 302362306a36Sopenharmony_ci} 302462306a36Sopenharmony_ci 302562306a36Sopenharmony_cistatic int ata_eh_revalidate_and_attach(struct ata_link *link, 302662306a36Sopenharmony_ci struct ata_device **r_failed_dev) 302762306a36Sopenharmony_ci{ 302862306a36Sopenharmony_ci struct ata_port *ap = link->ap; 302962306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 303062306a36Sopenharmony_ci struct ata_device *dev; 303162306a36Sopenharmony_ci unsigned int new_mask = 0; 303262306a36Sopenharmony_ci unsigned long flags; 303362306a36Sopenharmony_ci int rc = 0; 303462306a36Sopenharmony_ci 303562306a36Sopenharmony_ci /* For PATA drive side cable detection to work, IDENTIFY must 303662306a36Sopenharmony_ci * be done backwards such that PDIAG- is released by the slave 303762306a36Sopenharmony_ci * device before the master device is identified. 303862306a36Sopenharmony_ci */ 303962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL_REVERSE) { 304062306a36Sopenharmony_ci unsigned int action = ata_eh_dev_action(dev); 304162306a36Sopenharmony_ci unsigned int readid_flags = 0; 304262306a36Sopenharmony_ci 304362306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_DID_RESET) 304462306a36Sopenharmony_ci readid_flags |= ATA_READID_POSTRESET; 304562306a36Sopenharmony_ci 304662306a36Sopenharmony_ci /* 304762306a36Sopenharmony_ci * When resuming, before executing any command, make sure to 304862306a36Sopenharmony_ci * transition the device to the active power mode. 304962306a36Sopenharmony_ci */ 305062306a36Sopenharmony_ci if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) { 305162306a36Sopenharmony_ci ata_dev_power_set_active(dev); 305262306a36Sopenharmony_ci ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); 305362306a36Sopenharmony_ci } 305462306a36Sopenharmony_ci 305562306a36Sopenharmony_ci if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { 305662306a36Sopenharmony_ci WARN_ON(dev->class == ATA_DEV_PMP); 305762306a36Sopenharmony_ci 305862306a36Sopenharmony_ci /* 305962306a36Sopenharmony_ci * The link may be in a deep sleep, wake it up. 306062306a36Sopenharmony_ci * 306162306a36Sopenharmony_ci * If the link is in deep sleep, ata_phys_link_offline() 306262306a36Sopenharmony_ci * will return true, causing the revalidation to fail, 306362306a36Sopenharmony_ci * which leads to a (potentially) needless hard reset. 306462306a36Sopenharmony_ci * 306562306a36Sopenharmony_ci * ata_eh_recover() will later restore the link policy 306662306a36Sopenharmony_ci * to ap->target_lpm_policy after revalidation is done. 306762306a36Sopenharmony_ci */ 306862306a36Sopenharmony_ci if (link->lpm_policy > ATA_LPM_MAX_POWER) { 306962306a36Sopenharmony_ci rc = ata_eh_set_lpm(link, ATA_LPM_MAX_POWER, 307062306a36Sopenharmony_ci r_failed_dev); 307162306a36Sopenharmony_ci if (rc) 307262306a36Sopenharmony_ci goto err; 307362306a36Sopenharmony_ci } 307462306a36Sopenharmony_ci 307562306a36Sopenharmony_ci if (ata_phys_link_offline(ata_dev_phys_link(dev))) { 307662306a36Sopenharmony_ci rc = -EIO; 307762306a36Sopenharmony_ci goto err; 307862306a36Sopenharmony_ci } 307962306a36Sopenharmony_ci 308062306a36Sopenharmony_ci ata_eh_about_to_do(link, dev, ATA_EH_REVALIDATE); 308162306a36Sopenharmony_ci rc = ata_dev_revalidate(dev, ehc->classes[dev->devno], 308262306a36Sopenharmony_ci readid_flags); 308362306a36Sopenharmony_ci if (rc) 308462306a36Sopenharmony_ci goto err; 308562306a36Sopenharmony_ci 308662306a36Sopenharmony_ci ata_eh_done(link, dev, ATA_EH_REVALIDATE); 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_ci /* Configuration may have changed, reconfigure 308962306a36Sopenharmony_ci * transfer mode. 309062306a36Sopenharmony_ci */ 309162306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_SETMODE; 309262306a36Sopenharmony_ci 309362306a36Sopenharmony_ci /* schedule the scsi_rescan_device() here */ 309462306a36Sopenharmony_ci schedule_delayed_work(&ap->scsi_rescan_task, 0); 309562306a36Sopenharmony_ci } else if (dev->class == ATA_DEV_UNKNOWN && 309662306a36Sopenharmony_ci ehc->tries[dev->devno] && 309762306a36Sopenharmony_ci ata_class_enabled(ehc->classes[dev->devno])) { 309862306a36Sopenharmony_ci /* Temporarily set dev->class, it will be 309962306a36Sopenharmony_ci * permanently set once all configurations are 310062306a36Sopenharmony_ci * complete. This is necessary because new 310162306a36Sopenharmony_ci * device configuration is done in two 310262306a36Sopenharmony_ci * separate loops. 310362306a36Sopenharmony_ci */ 310462306a36Sopenharmony_ci dev->class = ehc->classes[dev->devno]; 310562306a36Sopenharmony_ci 310662306a36Sopenharmony_ci if (dev->class == ATA_DEV_PMP) 310762306a36Sopenharmony_ci rc = sata_pmp_attach(dev); 310862306a36Sopenharmony_ci else 310962306a36Sopenharmony_ci rc = ata_dev_read_id(dev, &dev->class, 311062306a36Sopenharmony_ci readid_flags, dev->id); 311162306a36Sopenharmony_ci 311262306a36Sopenharmony_ci /* read_id might have changed class, store and reset */ 311362306a36Sopenharmony_ci ehc->classes[dev->devno] = dev->class; 311462306a36Sopenharmony_ci dev->class = ATA_DEV_UNKNOWN; 311562306a36Sopenharmony_ci 311662306a36Sopenharmony_ci switch (rc) { 311762306a36Sopenharmony_ci case 0: 311862306a36Sopenharmony_ci /* clear error info accumulated during probe */ 311962306a36Sopenharmony_ci ata_ering_clear(&dev->ering); 312062306a36Sopenharmony_ci new_mask |= 1 << dev->devno; 312162306a36Sopenharmony_ci break; 312262306a36Sopenharmony_ci case -ENOENT: 312362306a36Sopenharmony_ci /* IDENTIFY was issued to non-existent 312462306a36Sopenharmony_ci * device. No need to reset. Just 312562306a36Sopenharmony_ci * thaw and ignore the device. 312662306a36Sopenharmony_ci */ 312762306a36Sopenharmony_ci ata_eh_thaw_port(ap); 312862306a36Sopenharmony_ci break; 312962306a36Sopenharmony_ci default: 313062306a36Sopenharmony_ci goto err; 313162306a36Sopenharmony_ci } 313262306a36Sopenharmony_ci } 313362306a36Sopenharmony_ci } 313462306a36Sopenharmony_ci 313562306a36Sopenharmony_ci /* PDIAG- should have been released, ask cable type if post-reset */ 313662306a36Sopenharmony_ci if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) { 313762306a36Sopenharmony_ci if (ap->ops->cable_detect) 313862306a36Sopenharmony_ci ap->cbl = ap->ops->cable_detect(ap); 313962306a36Sopenharmony_ci ata_force_cbl(ap); 314062306a36Sopenharmony_ci } 314162306a36Sopenharmony_ci 314262306a36Sopenharmony_ci /* Configure new devices forward such that user doesn't see 314362306a36Sopenharmony_ci * device detection messages backwards. 314462306a36Sopenharmony_ci */ 314562306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 314662306a36Sopenharmony_ci if (!(new_mask & (1 << dev->devno))) 314762306a36Sopenharmony_ci continue; 314862306a36Sopenharmony_ci 314962306a36Sopenharmony_ci dev->class = ehc->classes[dev->devno]; 315062306a36Sopenharmony_ci 315162306a36Sopenharmony_ci if (dev->class == ATA_DEV_PMP) 315262306a36Sopenharmony_ci continue; 315362306a36Sopenharmony_ci 315462306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_PRINTINFO; 315562306a36Sopenharmony_ci rc = ata_dev_configure(dev); 315662306a36Sopenharmony_ci ehc->i.flags &= ~ATA_EHI_PRINTINFO; 315762306a36Sopenharmony_ci if (rc) { 315862306a36Sopenharmony_ci dev->class = ATA_DEV_UNKNOWN; 315962306a36Sopenharmony_ci goto err; 316062306a36Sopenharmony_ci } 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 316362306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; 316462306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 316562306a36Sopenharmony_ci 316662306a36Sopenharmony_ci /* new device discovered, configure xfermode */ 316762306a36Sopenharmony_ci ehc->i.flags |= ATA_EHI_SETMODE; 316862306a36Sopenharmony_ci } 316962306a36Sopenharmony_ci 317062306a36Sopenharmony_ci return 0; 317162306a36Sopenharmony_ci 317262306a36Sopenharmony_ci err: 317362306a36Sopenharmony_ci *r_failed_dev = dev; 317462306a36Sopenharmony_ci return rc; 317562306a36Sopenharmony_ci} 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci/** 317862306a36Sopenharmony_ci * ata_set_mode - Program timings and issue SET FEATURES - XFER 317962306a36Sopenharmony_ci * @link: link on which timings will be programmed 318062306a36Sopenharmony_ci * @r_failed_dev: out parameter for failed device 318162306a36Sopenharmony_ci * 318262306a36Sopenharmony_ci * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If 318362306a36Sopenharmony_ci * ata_set_mode() fails, pointer to the failing device is 318462306a36Sopenharmony_ci * returned in @r_failed_dev. 318562306a36Sopenharmony_ci * 318662306a36Sopenharmony_ci * LOCKING: 318762306a36Sopenharmony_ci * PCI/etc. bus probe sem. 318862306a36Sopenharmony_ci * 318962306a36Sopenharmony_ci * RETURNS: 319062306a36Sopenharmony_ci * 0 on success, negative errno otherwise 319162306a36Sopenharmony_ci */ 319262306a36Sopenharmony_ciint ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) 319362306a36Sopenharmony_ci{ 319462306a36Sopenharmony_ci struct ata_port *ap = link->ap; 319562306a36Sopenharmony_ci struct ata_device *dev; 319662306a36Sopenharmony_ci int rc; 319762306a36Sopenharmony_ci 319862306a36Sopenharmony_ci /* if data transfer is verified, clear DUBIOUS_XFER on ering top */ 319962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 320062306a36Sopenharmony_ci if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) { 320162306a36Sopenharmony_ci struct ata_ering_entry *ent; 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_ci ent = ata_ering_top(&dev->ering); 320462306a36Sopenharmony_ci if (ent) 320562306a36Sopenharmony_ci ent->eflags &= ~ATA_EFLAG_DUBIOUS_XFER; 320662306a36Sopenharmony_ci } 320762306a36Sopenharmony_ci } 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_ci /* has private set_mode? */ 321062306a36Sopenharmony_ci if (ap->ops->set_mode) 321162306a36Sopenharmony_ci rc = ap->ops->set_mode(link, r_failed_dev); 321262306a36Sopenharmony_ci else 321362306a36Sopenharmony_ci rc = ata_do_set_mode(link, r_failed_dev); 321462306a36Sopenharmony_ci 321562306a36Sopenharmony_ci /* if transfer mode has changed, set DUBIOUS_XFER on device */ 321662306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 321762306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 321862306a36Sopenharmony_ci u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno]; 321962306a36Sopenharmony_ci u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno)); 322062306a36Sopenharmony_ci 322162306a36Sopenharmony_ci if (dev->xfer_mode != saved_xfer_mode || 322262306a36Sopenharmony_ci ata_ncq_enabled(dev) != saved_ncq) 322362306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_DUBIOUS_XFER; 322462306a36Sopenharmony_ci } 322562306a36Sopenharmony_ci 322662306a36Sopenharmony_ci return rc; 322762306a36Sopenharmony_ci} 322862306a36Sopenharmony_ci 322962306a36Sopenharmony_ci/** 323062306a36Sopenharmony_ci * atapi_eh_clear_ua - Clear ATAPI UNIT ATTENTION after reset 323162306a36Sopenharmony_ci * @dev: ATAPI device to clear UA for 323262306a36Sopenharmony_ci * 323362306a36Sopenharmony_ci * Resets and other operations can make an ATAPI device raise 323462306a36Sopenharmony_ci * UNIT ATTENTION which causes the next operation to fail. This 323562306a36Sopenharmony_ci * function clears UA. 323662306a36Sopenharmony_ci * 323762306a36Sopenharmony_ci * LOCKING: 323862306a36Sopenharmony_ci * EH context (may sleep). 323962306a36Sopenharmony_ci * 324062306a36Sopenharmony_ci * RETURNS: 324162306a36Sopenharmony_ci * 0 on success, -errno on failure. 324262306a36Sopenharmony_ci */ 324362306a36Sopenharmony_cistatic int atapi_eh_clear_ua(struct ata_device *dev) 324462306a36Sopenharmony_ci{ 324562306a36Sopenharmony_ci int i; 324662306a36Sopenharmony_ci 324762306a36Sopenharmony_ci for (i = 0; i < ATA_EH_UA_TRIES; i++) { 324862306a36Sopenharmony_ci u8 *sense_buffer = dev->link->ap->sector_buf; 324962306a36Sopenharmony_ci u8 sense_key = 0; 325062306a36Sopenharmony_ci unsigned int err_mask; 325162306a36Sopenharmony_ci 325262306a36Sopenharmony_ci err_mask = atapi_eh_tur(dev, &sense_key); 325362306a36Sopenharmony_ci if (err_mask != 0 && err_mask != AC_ERR_DEV) { 325462306a36Sopenharmony_ci ata_dev_warn(dev, 325562306a36Sopenharmony_ci "TEST_UNIT_READY failed (err_mask=0x%x)\n", 325662306a36Sopenharmony_ci err_mask); 325762306a36Sopenharmony_ci return -EIO; 325862306a36Sopenharmony_ci } 325962306a36Sopenharmony_ci 326062306a36Sopenharmony_ci if (!err_mask || sense_key != UNIT_ATTENTION) 326162306a36Sopenharmony_ci return 0; 326262306a36Sopenharmony_ci 326362306a36Sopenharmony_ci err_mask = atapi_eh_request_sense(dev, sense_buffer, sense_key); 326462306a36Sopenharmony_ci if (err_mask) { 326562306a36Sopenharmony_ci ata_dev_warn(dev, "failed to clear " 326662306a36Sopenharmony_ci "UNIT ATTENTION (err_mask=0x%x)\n", err_mask); 326762306a36Sopenharmony_ci return -EIO; 326862306a36Sopenharmony_ci } 326962306a36Sopenharmony_ci } 327062306a36Sopenharmony_ci 327162306a36Sopenharmony_ci ata_dev_warn(dev, "UNIT ATTENTION persists after %d tries\n", 327262306a36Sopenharmony_ci ATA_EH_UA_TRIES); 327362306a36Sopenharmony_ci 327462306a36Sopenharmony_ci return 0; 327562306a36Sopenharmony_ci} 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci/** 327862306a36Sopenharmony_ci * ata_eh_maybe_retry_flush - Retry FLUSH if necessary 327962306a36Sopenharmony_ci * @dev: ATA device which may need FLUSH retry 328062306a36Sopenharmony_ci * 328162306a36Sopenharmony_ci * If @dev failed FLUSH, it needs to be reported upper layer 328262306a36Sopenharmony_ci * immediately as it means that @dev failed to remap and already 328362306a36Sopenharmony_ci * lost at least a sector and further FLUSH retrials won't make 328462306a36Sopenharmony_ci * any difference to the lost sector. However, if FLUSH failed 328562306a36Sopenharmony_ci * for other reasons, for example transmission error, FLUSH needs 328662306a36Sopenharmony_ci * to be retried. 328762306a36Sopenharmony_ci * 328862306a36Sopenharmony_ci * This function determines whether FLUSH failure retry is 328962306a36Sopenharmony_ci * necessary and performs it if so. 329062306a36Sopenharmony_ci * 329162306a36Sopenharmony_ci * RETURNS: 329262306a36Sopenharmony_ci * 0 if EH can continue, -errno if EH needs to be repeated. 329362306a36Sopenharmony_ci */ 329462306a36Sopenharmony_cistatic int ata_eh_maybe_retry_flush(struct ata_device *dev) 329562306a36Sopenharmony_ci{ 329662306a36Sopenharmony_ci struct ata_link *link = dev->link; 329762306a36Sopenharmony_ci struct ata_port *ap = link->ap; 329862306a36Sopenharmony_ci struct ata_queued_cmd *qc; 329962306a36Sopenharmony_ci struct ata_taskfile tf; 330062306a36Sopenharmony_ci unsigned int err_mask; 330162306a36Sopenharmony_ci int rc = 0; 330262306a36Sopenharmony_ci 330362306a36Sopenharmony_ci /* did flush fail for this device? */ 330462306a36Sopenharmony_ci if (!ata_tag_valid(link->active_tag)) 330562306a36Sopenharmony_ci return 0; 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci qc = __ata_qc_from_tag(ap, link->active_tag); 330862306a36Sopenharmony_ci if (qc->dev != dev || (qc->tf.command != ATA_CMD_FLUSH_EXT && 330962306a36Sopenharmony_ci qc->tf.command != ATA_CMD_FLUSH)) 331062306a36Sopenharmony_ci return 0; 331162306a36Sopenharmony_ci 331262306a36Sopenharmony_ci /* if the device failed it, it should be reported to upper layers */ 331362306a36Sopenharmony_ci if (qc->err_mask & AC_ERR_DEV) 331462306a36Sopenharmony_ci return 0; 331562306a36Sopenharmony_ci 331662306a36Sopenharmony_ci /* flush failed for some other reason, give it another shot */ 331762306a36Sopenharmony_ci ata_tf_init(dev, &tf); 331862306a36Sopenharmony_ci 331962306a36Sopenharmony_ci tf.command = qc->tf.command; 332062306a36Sopenharmony_ci tf.flags |= ATA_TFLAG_DEVICE; 332162306a36Sopenharmony_ci tf.protocol = ATA_PROT_NODATA; 332262306a36Sopenharmony_ci 332362306a36Sopenharmony_ci ata_dev_warn(dev, "retrying FLUSH 0x%x Emask 0x%x\n", 332462306a36Sopenharmony_ci tf.command, qc->err_mask); 332562306a36Sopenharmony_ci 332662306a36Sopenharmony_ci err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); 332762306a36Sopenharmony_ci if (!err_mask) { 332862306a36Sopenharmony_ci /* 332962306a36Sopenharmony_ci * FLUSH is complete but there's no way to 333062306a36Sopenharmony_ci * successfully complete a failed command from EH. 333162306a36Sopenharmony_ci * Making sure retry is allowed at least once and 333262306a36Sopenharmony_ci * retrying it should do the trick - whatever was in 333362306a36Sopenharmony_ci * the cache is already on the platter and this won't 333462306a36Sopenharmony_ci * cause infinite loop. 333562306a36Sopenharmony_ci */ 333662306a36Sopenharmony_ci qc->scsicmd->allowed = max(qc->scsicmd->allowed, 1); 333762306a36Sopenharmony_ci } else { 333862306a36Sopenharmony_ci ata_dev_warn(dev, "FLUSH failed Emask 0x%x\n", 333962306a36Sopenharmony_ci err_mask); 334062306a36Sopenharmony_ci rc = -EIO; 334162306a36Sopenharmony_ci 334262306a36Sopenharmony_ci /* if device failed it, report it to upper layers */ 334362306a36Sopenharmony_ci if (err_mask & AC_ERR_DEV) { 334462306a36Sopenharmony_ci qc->err_mask |= AC_ERR_DEV; 334562306a36Sopenharmony_ci qc->result_tf = tf; 334662306a36Sopenharmony_ci if (!ata_port_is_frozen(ap)) 334762306a36Sopenharmony_ci rc = 0; 334862306a36Sopenharmony_ci } 334962306a36Sopenharmony_ci } 335062306a36Sopenharmony_ci return rc; 335162306a36Sopenharmony_ci} 335262306a36Sopenharmony_ci 335362306a36Sopenharmony_ci/** 335462306a36Sopenharmony_ci * ata_eh_set_lpm - configure SATA interface power management 335562306a36Sopenharmony_ci * @link: link to configure power management 335662306a36Sopenharmony_ci * @policy: the link power management policy 335762306a36Sopenharmony_ci * @r_failed_dev: out parameter for failed device 335862306a36Sopenharmony_ci * 335962306a36Sopenharmony_ci * Enable SATA Interface power management. This will enable 336062306a36Sopenharmony_ci * Device Interface Power Management (DIPM) for min_power and 336162306a36Sopenharmony_ci * medium_power_with_dipm policies, and then call driver specific 336262306a36Sopenharmony_ci * callbacks for enabling Host Initiated Power management. 336362306a36Sopenharmony_ci * 336462306a36Sopenharmony_ci * LOCKING: 336562306a36Sopenharmony_ci * EH context. 336662306a36Sopenharmony_ci * 336762306a36Sopenharmony_ci * RETURNS: 336862306a36Sopenharmony_ci * 0 on success, -errno on failure. 336962306a36Sopenharmony_ci */ 337062306a36Sopenharmony_cistatic int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, 337162306a36Sopenharmony_ci struct ata_device **r_failed_dev) 337262306a36Sopenharmony_ci{ 337362306a36Sopenharmony_ci struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; 337462306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 337562306a36Sopenharmony_ci struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; 337662306a36Sopenharmony_ci enum ata_lpm_policy old_policy = link->lpm_policy; 337762306a36Sopenharmony_ci bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM; 337862306a36Sopenharmony_ci unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; 337962306a36Sopenharmony_ci unsigned int err_mask; 338062306a36Sopenharmony_ci int rc; 338162306a36Sopenharmony_ci 338262306a36Sopenharmony_ci /* if the link or host doesn't do LPM, noop */ 338362306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_SATA_HOST) || 338462306a36Sopenharmony_ci (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) 338562306a36Sopenharmony_ci return 0; 338662306a36Sopenharmony_ci 338762306a36Sopenharmony_ci /* 338862306a36Sopenharmony_ci * DIPM is enabled only for MIN_POWER as some devices 338962306a36Sopenharmony_ci * misbehave when the host NACKs transition to SLUMBER. Order 339062306a36Sopenharmony_ci * device and link configurations such that the host always 339162306a36Sopenharmony_ci * allows DIPM requests. 339262306a36Sopenharmony_ci */ 339362306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 339462306a36Sopenharmony_ci bool hipm = ata_id_has_hipm(dev->id); 339562306a36Sopenharmony_ci bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; 339662306a36Sopenharmony_ci 339762306a36Sopenharmony_ci /* find the first enabled and LPM enabled devices */ 339862306a36Sopenharmony_ci if (!link_dev) 339962306a36Sopenharmony_ci link_dev = dev; 340062306a36Sopenharmony_ci 340162306a36Sopenharmony_ci if (!lpm_dev && (hipm || dipm)) 340262306a36Sopenharmony_ci lpm_dev = dev; 340362306a36Sopenharmony_ci 340462306a36Sopenharmony_ci hints &= ~ATA_LPM_EMPTY; 340562306a36Sopenharmony_ci if (!hipm) 340662306a36Sopenharmony_ci hints &= ~ATA_LPM_HIPM; 340762306a36Sopenharmony_ci 340862306a36Sopenharmony_ci /* disable DIPM before changing link config */ 340962306a36Sopenharmony_ci if (policy < ATA_LPM_MED_POWER_WITH_DIPM && dipm) { 341062306a36Sopenharmony_ci err_mask = ata_dev_set_feature(dev, 341162306a36Sopenharmony_ci SETFEATURES_SATA_DISABLE, SATA_DIPM); 341262306a36Sopenharmony_ci if (err_mask && err_mask != AC_ERR_DEV) { 341362306a36Sopenharmony_ci ata_dev_warn(dev, 341462306a36Sopenharmony_ci "failed to disable DIPM, Emask 0x%x\n", 341562306a36Sopenharmony_ci err_mask); 341662306a36Sopenharmony_ci rc = -EIO; 341762306a36Sopenharmony_ci goto fail; 341862306a36Sopenharmony_ci } 341962306a36Sopenharmony_ci } 342062306a36Sopenharmony_ci } 342162306a36Sopenharmony_ci 342262306a36Sopenharmony_ci if (ap) { 342362306a36Sopenharmony_ci rc = ap->ops->set_lpm(link, policy, hints); 342462306a36Sopenharmony_ci if (!rc && ap->slave_link) 342562306a36Sopenharmony_ci rc = ap->ops->set_lpm(ap->slave_link, policy, hints); 342662306a36Sopenharmony_ci } else 342762306a36Sopenharmony_ci rc = sata_pmp_set_lpm(link, policy, hints); 342862306a36Sopenharmony_ci 342962306a36Sopenharmony_ci /* 343062306a36Sopenharmony_ci * Attribute link config failure to the first (LPM) enabled 343162306a36Sopenharmony_ci * device on the link. 343262306a36Sopenharmony_ci */ 343362306a36Sopenharmony_ci if (rc) { 343462306a36Sopenharmony_ci if (rc == -EOPNOTSUPP) { 343562306a36Sopenharmony_ci link->flags |= ATA_LFLAG_NO_LPM; 343662306a36Sopenharmony_ci return 0; 343762306a36Sopenharmony_ci } 343862306a36Sopenharmony_ci dev = lpm_dev ? lpm_dev : link_dev; 343962306a36Sopenharmony_ci goto fail; 344062306a36Sopenharmony_ci } 344162306a36Sopenharmony_ci 344262306a36Sopenharmony_ci /* 344362306a36Sopenharmony_ci * Low level driver acked the transition. Issue DIPM command 344462306a36Sopenharmony_ci * with the new policy set. 344562306a36Sopenharmony_ci */ 344662306a36Sopenharmony_ci link->lpm_policy = policy; 344762306a36Sopenharmony_ci if (ap && ap->slave_link) 344862306a36Sopenharmony_ci ap->slave_link->lpm_policy = policy; 344962306a36Sopenharmony_ci 345062306a36Sopenharmony_ci /* host config updated, enable DIPM if transitioning to MIN_POWER */ 345162306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 345262306a36Sopenharmony_ci if (policy >= ATA_LPM_MED_POWER_WITH_DIPM && !no_dipm && 345362306a36Sopenharmony_ci ata_id_has_dipm(dev->id)) { 345462306a36Sopenharmony_ci err_mask = ata_dev_set_feature(dev, 345562306a36Sopenharmony_ci SETFEATURES_SATA_ENABLE, SATA_DIPM); 345662306a36Sopenharmony_ci if (err_mask && err_mask != AC_ERR_DEV) { 345762306a36Sopenharmony_ci ata_dev_warn(dev, 345862306a36Sopenharmony_ci "failed to enable DIPM, Emask 0x%x\n", 345962306a36Sopenharmony_ci err_mask); 346062306a36Sopenharmony_ci rc = -EIO; 346162306a36Sopenharmony_ci goto fail; 346262306a36Sopenharmony_ci } 346362306a36Sopenharmony_ci } 346462306a36Sopenharmony_ci } 346562306a36Sopenharmony_ci 346662306a36Sopenharmony_ci link->last_lpm_change = jiffies; 346762306a36Sopenharmony_ci link->flags |= ATA_LFLAG_CHANGED; 346862306a36Sopenharmony_ci 346962306a36Sopenharmony_ci return 0; 347062306a36Sopenharmony_ci 347162306a36Sopenharmony_cifail: 347262306a36Sopenharmony_ci /* restore the old policy */ 347362306a36Sopenharmony_ci link->lpm_policy = old_policy; 347462306a36Sopenharmony_ci if (ap && ap->slave_link) 347562306a36Sopenharmony_ci ap->slave_link->lpm_policy = old_policy; 347662306a36Sopenharmony_ci 347762306a36Sopenharmony_ci /* if no device or only one more chance is left, disable LPM */ 347862306a36Sopenharmony_ci if (!dev || ehc->tries[dev->devno] <= 2) { 347962306a36Sopenharmony_ci ata_link_warn(link, "disabling LPM on the link\n"); 348062306a36Sopenharmony_ci link->flags |= ATA_LFLAG_NO_LPM; 348162306a36Sopenharmony_ci } 348262306a36Sopenharmony_ci if (r_failed_dev) 348362306a36Sopenharmony_ci *r_failed_dev = dev; 348462306a36Sopenharmony_ci return rc; 348562306a36Sopenharmony_ci} 348662306a36Sopenharmony_ci 348762306a36Sopenharmony_ciint ata_link_nr_enabled(struct ata_link *link) 348862306a36Sopenharmony_ci{ 348962306a36Sopenharmony_ci struct ata_device *dev; 349062306a36Sopenharmony_ci int cnt = 0; 349162306a36Sopenharmony_ci 349262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) 349362306a36Sopenharmony_ci cnt++; 349462306a36Sopenharmony_ci return cnt; 349562306a36Sopenharmony_ci} 349662306a36Sopenharmony_ci 349762306a36Sopenharmony_cistatic int ata_link_nr_vacant(struct ata_link *link) 349862306a36Sopenharmony_ci{ 349962306a36Sopenharmony_ci struct ata_device *dev; 350062306a36Sopenharmony_ci int cnt = 0; 350162306a36Sopenharmony_ci 350262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 350362306a36Sopenharmony_ci if (dev->class == ATA_DEV_UNKNOWN) 350462306a36Sopenharmony_ci cnt++; 350562306a36Sopenharmony_ci return cnt; 350662306a36Sopenharmony_ci} 350762306a36Sopenharmony_ci 350862306a36Sopenharmony_cistatic int ata_eh_skip_recovery(struct ata_link *link) 350962306a36Sopenharmony_ci{ 351062306a36Sopenharmony_ci struct ata_port *ap = link->ap; 351162306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 351262306a36Sopenharmony_ci struct ata_device *dev; 351362306a36Sopenharmony_ci 351462306a36Sopenharmony_ci /* skip disabled links */ 351562306a36Sopenharmony_ci if (link->flags & ATA_LFLAG_DISABLED) 351662306a36Sopenharmony_ci return 1; 351762306a36Sopenharmony_ci 351862306a36Sopenharmony_ci /* skip if explicitly requested */ 351962306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_NO_RECOVERY) 352062306a36Sopenharmony_ci return 1; 352162306a36Sopenharmony_ci 352262306a36Sopenharmony_ci /* thaw frozen port and recover failed devices */ 352362306a36Sopenharmony_ci if (ata_port_is_frozen(ap) || ata_link_nr_enabled(link)) 352462306a36Sopenharmony_ci return 0; 352562306a36Sopenharmony_ci 352662306a36Sopenharmony_ci /* reset at least once if reset is requested */ 352762306a36Sopenharmony_ci if ((ehc->i.action & ATA_EH_RESET) && 352862306a36Sopenharmony_ci !(ehc->i.flags & ATA_EHI_DID_RESET)) 352962306a36Sopenharmony_ci return 0; 353062306a36Sopenharmony_ci 353162306a36Sopenharmony_ci /* skip if class codes for all vacant slots are ATA_DEV_NONE */ 353262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 353362306a36Sopenharmony_ci if (dev->class == ATA_DEV_UNKNOWN && 353462306a36Sopenharmony_ci ehc->classes[dev->devno] != ATA_DEV_NONE) 353562306a36Sopenharmony_ci return 0; 353662306a36Sopenharmony_ci } 353762306a36Sopenharmony_ci 353862306a36Sopenharmony_ci return 1; 353962306a36Sopenharmony_ci} 354062306a36Sopenharmony_ci 354162306a36Sopenharmony_cistatic int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg) 354262306a36Sopenharmony_ci{ 354362306a36Sopenharmony_ci u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL); 354462306a36Sopenharmony_ci u64 now = get_jiffies_64(); 354562306a36Sopenharmony_ci int *trials = void_arg; 354662306a36Sopenharmony_ci 354762306a36Sopenharmony_ci if ((ent->eflags & ATA_EFLAG_OLD_ER) || 354862306a36Sopenharmony_ci (ent->timestamp < now - min(now, interval))) 354962306a36Sopenharmony_ci return -1; 355062306a36Sopenharmony_ci 355162306a36Sopenharmony_ci (*trials)++; 355262306a36Sopenharmony_ci return 0; 355362306a36Sopenharmony_ci} 355462306a36Sopenharmony_ci 355562306a36Sopenharmony_cistatic int ata_eh_schedule_probe(struct ata_device *dev) 355662306a36Sopenharmony_ci{ 355762306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 355862306a36Sopenharmony_ci struct ata_link *link = ata_dev_phys_link(dev); 355962306a36Sopenharmony_ci int trials = 0; 356062306a36Sopenharmony_ci 356162306a36Sopenharmony_ci if (!(ehc->i.probe_mask & (1 << dev->devno)) || 356262306a36Sopenharmony_ci (ehc->did_probe_mask & (1 << dev->devno))) 356362306a36Sopenharmony_ci return 0; 356462306a36Sopenharmony_ci 356562306a36Sopenharmony_ci ata_eh_detach_dev(dev); 356662306a36Sopenharmony_ci ata_dev_init(dev); 356762306a36Sopenharmony_ci ehc->did_probe_mask |= (1 << dev->devno); 356862306a36Sopenharmony_ci ehc->i.action |= ATA_EH_RESET; 356962306a36Sopenharmony_ci ehc->saved_xfer_mode[dev->devno] = 0; 357062306a36Sopenharmony_ci ehc->saved_ncq_enabled &= ~(1 << dev->devno); 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci /* the link maybe in a deep sleep, wake it up */ 357362306a36Sopenharmony_ci if (link->lpm_policy > ATA_LPM_MAX_POWER) { 357462306a36Sopenharmony_ci if (ata_is_host_link(link)) 357562306a36Sopenharmony_ci link->ap->ops->set_lpm(link, ATA_LPM_MAX_POWER, 357662306a36Sopenharmony_ci ATA_LPM_EMPTY); 357762306a36Sopenharmony_ci else 357862306a36Sopenharmony_ci sata_pmp_set_lpm(link, ATA_LPM_MAX_POWER, 357962306a36Sopenharmony_ci ATA_LPM_EMPTY); 358062306a36Sopenharmony_ci } 358162306a36Sopenharmony_ci 358262306a36Sopenharmony_ci /* Record and count probe trials on the ering. The specific 358362306a36Sopenharmony_ci * error mask used is irrelevant. Because a successful device 358462306a36Sopenharmony_ci * detection clears the ering, this count accumulates only if 358562306a36Sopenharmony_ci * there are consecutive failed probes. 358662306a36Sopenharmony_ci * 358762306a36Sopenharmony_ci * If the count is equal to or higher than ATA_EH_PROBE_TRIALS 358862306a36Sopenharmony_ci * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is 358962306a36Sopenharmony_ci * forced to 1.5Gbps. 359062306a36Sopenharmony_ci * 359162306a36Sopenharmony_ci * This is to work around cases where failed link speed 359262306a36Sopenharmony_ci * negotiation results in device misdetection leading to 359362306a36Sopenharmony_ci * infinite DEVXCHG or PHRDY CHG events. 359462306a36Sopenharmony_ci */ 359562306a36Sopenharmony_ci ata_ering_record(&dev->ering, 0, AC_ERR_OTHER); 359662306a36Sopenharmony_ci ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials); 359762306a36Sopenharmony_ci 359862306a36Sopenharmony_ci if (trials > ATA_EH_PROBE_TRIALS) 359962306a36Sopenharmony_ci sata_down_spd_limit(link, 1); 360062306a36Sopenharmony_ci 360162306a36Sopenharmony_ci return 1; 360262306a36Sopenharmony_ci} 360362306a36Sopenharmony_ci 360462306a36Sopenharmony_cistatic int ata_eh_handle_dev_fail(struct ata_device *dev, int err) 360562306a36Sopenharmony_ci{ 360662306a36Sopenharmony_ci struct ata_eh_context *ehc = &dev->link->eh_context; 360762306a36Sopenharmony_ci 360862306a36Sopenharmony_ci /* -EAGAIN from EH routine indicates retry without prejudice. 360962306a36Sopenharmony_ci * The requester is responsible for ensuring forward progress. 361062306a36Sopenharmony_ci */ 361162306a36Sopenharmony_ci if (err != -EAGAIN) 361262306a36Sopenharmony_ci ehc->tries[dev->devno]--; 361362306a36Sopenharmony_ci 361462306a36Sopenharmony_ci switch (err) { 361562306a36Sopenharmony_ci case -ENODEV: 361662306a36Sopenharmony_ci /* device missing or wrong IDENTIFY data, schedule probing */ 361762306a36Sopenharmony_ci ehc->i.probe_mask |= (1 << dev->devno); 361862306a36Sopenharmony_ci fallthrough; 361962306a36Sopenharmony_ci case -EINVAL: 362062306a36Sopenharmony_ci /* give it just one more chance */ 362162306a36Sopenharmony_ci ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); 362262306a36Sopenharmony_ci fallthrough; 362362306a36Sopenharmony_ci case -EIO: 362462306a36Sopenharmony_ci if (ehc->tries[dev->devno] == 1) { 362562306a36Sopenharmony_ci /* This is the last chance, better to slow 362662306a36Sopenharmony_ci * down than lose it. 362762306a36Sopenharmony_ci */ 362862306a36Sopenharmony_ci sata_down_spd_limit(ata_dev_phys_link(dev), 0); 362962306a36Sopenharmony_ci if (dev->pio_mode > XFER_PIO_0) 363062306a36Sopenharmony_ci ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); 363162306a36Sopenharmony_ci } 363262306a36Sopenharmony_ci } 363362306a36Sopenharmony_ci 363462306a36Sopenharmony_ci if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) { 363562306a36Sopenharmony_ci /* disable device if it has used up all its chances */ 363662306a36Sopenharmony_ci ata_dev_disable(dev); 363762306a36Sopenharmony_ci 363862306a36Sopenharmony_ci /* detach if offline */ 363962306a36Sopenharmony_ci if (ata_phys_link_offline(ata_dev_phys_link(dev))) 364062306a36Sopenharmony_ci ata_eh_detach_dev(dev); 364162306a36Sopenharmony_ci 364262306a36Sopenharmony_ci /* schedule probe if necessary */ 364362306a36Sopenharmony_ci if (ata_eh_schedule_probe(dev)) { 364462306a36Sopenharmony_ci ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; 364562306a36Sopenharmony_ci memset(ehc->cmd_timeout_idx[dev->devno], 0, 364662306a36Sopenharmony_ci sizeof(ehc->cmd_timeout_idx[dev->devno])); 364762306a36Sopenharmony_ci } 364862306a36Sopenharmony_ci 364962306a36Sopenharmony_ci return 1; 365062306a36Sopenharmony_ci } else { 365162306a36Sopenharmony_ci ehc->i.action |= ATA_EH_RESET; 365262306a36Sopenharmony_ci return 0; 365362306a36Sopenharmony_ci } 365462306a36Sopenharmony_ci} 365562306a36Sopenharmony_ci 365662306a36Sopenharmony_ci/** 365762306a36Sopenharmony_ci * ata_eh_recover - recover host port after error 365862306a36Sopenharmony_ci * @ap: host port to recover 365962306a36Sopenharmony_ci * @prereset: prereset method (can be NULL) 366062306a36Sopenharmony_ci * @softreset: softreset method (can be NULL) 366162306a36Sopenharmony_ci * @hardreset: hardreset method (can be NULL) 366262306a36Sopenharmony_ci * @postreset: postreset method (can be NULL) 366362306a36Sopenharmony_ci * @r_failed_link: out parameter for failed link 366462306a36Sopenharmony_ci * 366562306a36Sopenharmony_ci * This is the alpha and omega, eum and yang, heart and soul of 366662306a36Sopenharmony_ci * libata exception handling. On entry, actions required to 366762306a36Sopenharmony_ci * recover each link and hotplug requests are recorded in the 366862306a36Sopenharmony_ci * link's eh_context. This function executes all the operations 366962306a36Sopenharmony_ci * with appropriate retrials and fallbacks to resurrect failed 367062306a36Sopenharmony_ci * devices, detach goners and greet newcomers. 367162306a36Sopenharmony_ci * 367262306a36Sopenharmony_ci * LOCKING: 367362306a36Sopenharmony_ci * Kernel thread context (may sleep). 367462306a36Sopenharmony_ci * 367562306a36Sopenharmony_ci * RETURNS: 367662306a36Sopenharmony_ci * 0 on success, -errno on failure. 367762306a36Sopenharmony_ci */ 367862306a36Sopenharmony_ciint ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, 367962306a36Sopenharmony_ci ata_reset_fn_t softreset, ata_reset_fn_t hardreset, 368062306a36Sopenharmony_ci ata_postreset_fn_t postreset, 368162306a36Sopenharmony_ci struct ata_link **r_failed_link) 368262306a36Sopenharmony_ci{ 368362306a36Sopenharmony_ci struct ata_link *link; 368462306a36Sopenharmony_ci struct ata_device *dev; 368562306a36Sopenharmony_ci int rc, nr_fails; 368662306a36Sopenharmony_ci unsigned long flags, deadline; 368762306a36Sopenharmony_ci 368862306a36Sopenharmony_ci /* prep for recovery */ 368962306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 369062306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 369162306a36Sopenharmony_ci 369262306a36Sopenharmony_ci /* re-enable link? */ 369362306a36Sopenharmony_ci if (ehc->i.action & ATA_EH_ENABLE_LINK) { 369462306a36Sopenharmony_ci ata_eh_about_to_do(link, NULL, ATA_EH_ENABLE_LINK); 369562306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 369662306a36Sopenharmony_ci link->flags &= ~ATA_LFLAG_DISABLED; 369762306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 369862306a36Sopenharmony_ci ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK); 369962306a36Sopenharmony_ci } 370062306a36Sopenharmony_ci 370162306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 370262306a36Sopenharmony_ci if (link->flags & ATA_LFLAG_NO_RETRY) 370362306a36Sopenharmony_ci ehc->tries[dev->devno] = 1; 370462306a36Sopenharmony_ci else 370562306a36Sopenharmony_ci ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; 370662306a36Sopenharmony_ci 370762306a36Sopenharmony_ci /* collect port action mask recorded in dev actions */ 370862306a36Sopenharmony_ci ehc->i.action |= ehc->i.dev_action[dev->devno] & 370962306a36Sopenharmony_ci ~ATA_EH_PERDEV_MASK; 371062306a36Sopenharmony_ci ehc->i.dev_action[dev->devno] &= ATA_EH_PERDEV_MASK; 371162306a36Sopenharmony_ci 371262306a36Sopenharmony_ci /* process hotplug request */ 371362306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_DETACH) 371462306a36Sopenharmony_ci ata_eh_detach_dev(dev); 371562306a36Sopenharmony_ci 371662306a36Sopenharmony_ci /* schedule probe if necessary */ 371762306a36Sopenharmony_ci if (!ata_dev_enabled(dev)) 371862306a36Sopenharmony_ci ata_eh_schedule_probe(dev); 371962306a36Sopenharmony_ci } 372062306a36Sopenharmony_ci } 372162306a36Sopenharmony_ci 372262306a36Sopenharmony_ci retry: 372362306a36Sopenharmony_ci rc = 0; 372462306a36Sopenharmony_ci 372562306a36Sopenharmony_ci /* if UNLOADING, finish immediately */ 372662306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_UNLOADING) 372762306a36Sopenharmony_ci goto out; 372862306a36Sopenharmony_ci 372962306a36Sopenharmony_ci /* prep for EH */ 373062306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 373162306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 373262306a36Sopenharmony_ci 373362306a36Sopenharmony_ci /* skip EH if possible. */ 373462306a36Sopenharmony_ci if (ata_eh_skip_recovery(link)) 373562306a36Sopenharmony_ci ehc->i.action = 0; 373662306a36Sopenharmony_ci 373762306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 373862306a36Sopenharmony_ci ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; 373962306a36Sopenharmony_ci } 374062306a36Sopenharmony_ci 374162306a36Sopenharmony_ci /* reset */ 374262306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 374362306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 374462306a36Sopenharmony_ci 374562306a36Sopenharmony_ci if (!(ehc->i.action & ATA_EH_RESET)) 374662306a36Sopenharmony_ci continue; 374762306a36Sopenharmony_ci 374862306a36Sopenharmony_ci rc = ata_eh_reset(link, ata_link_nr_vacant(link), 374962306a36Sopenharmony_ci prereset, softreset, hardreset, postreset); 375062306a36Sopenharmony_ci if (rc) { 375162306a36Sopenharmony_ci ata_link_err(link, "reset failed, giving up\n"); 375262306a36Sopenharmony_ci goto out; 375362306a36Sopenharmony_ci } 375462306a36Sopenharmony_ci } 375562306a36Sopenharmony_ci 375662306a36Sopenharmony_ci do { 375762306a36Sopenharmony_ci unsigned long now; 375862306a36Sopenharmony_ci 375962306a36Sopenharmony_ci /* 376062306a36Sopenharmony_ci * clears ATA_EH_PARK in eh_info and resets 376162306a36Sopenharmony_ci * ap->park_req_pending 376262306a36Sopenharmony_ci */ 376362306a36Sopenharmony_ci ata_eh_pull_park_action(ap); 376462306a36Sopenharmony_ci 376562306a36Sopenharmony_ci deadline = jiffies; 376662306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 376762306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 376862306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 376962306a36Sopenharmony_ci unsigned long tmp; 377062306a36Sopenharmony_ci 377162306a36Sopenharmony_ci if (dev->class != ATA_DEV_ATA && 377262306a36Sopenharmony_ci dev->class != ATA_DEV_ZAC) 377362306a36Sopenharmony_ci continue; 377462306a36Sopenharmony_ci if (!(ehc->i.dev_action[dev->devno] & 377562306a36Sopenharmony_ci ATA_EH_PARK)) 377662306a36Sopenharmony_ci continue; 377762306a36Sopenharmony_ci tmp = dev->unpark_deadline; 377862306a36Sopenharmony_ci if (time_before(deadline, tmp)) 377962306a36Sopenharmony_ci deadline = tmp; 378062306a36Sopenharmony_ci else if (time_before_eq(tmp, jiffies)) 378162306a36Sopenharmony_ci continue; 378262306a36Sopenharmony_ci if (ehc->unloaded_mask & (1 << dev->devno)) 378362306a36Sopenharmony_ci continue; 378462306a36Sopenharmony_ci 378562306a36Sopenharmony_ci ata_eh_park_issue_cmd(dev, 1); 378662306a36Sopenharmony_ci } 378762306a36Sopenharmony_ci } 378862306a36Sopenharmony_ci 378962306a36Sopenharmony_ci now = jiffies; 379062306a36Sopenharmony_ci if (time_before_eq(deadline, now)) 379162306a36Sopenharmony_ci break; 379262306a36Sopenharmony_ci 379362306a36Sopenharmony_ci ata_eh_release(ap); 379462306a36Sopenharmony_ci deadline = wait_for_completion_timeout(&ap->park_req_pending, 379562306a36Sopenharmony_ci deadline - now); 379662306a36Sopenharmony_ci ata_eh_acquire(ap); 379762306a36Sopenharmony_ci } while (deadline); 379862306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 379962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 380062306a36Sopenharmony_ci if (!(link->eh_context.unloaded_mask & 380162306a36Sopenharmony_ci (1 << dev->devno))) 380262306a36Sopenharmony_ci continue; 380362306a36Sopenharmony_ci 380462306a36Sopenharmony_ci ata_eh_park_issue_cmd(dev, 0); 380562306a36Sopenharmony_ci ata_eh_done(link, dev, ATA_EH_PARK); 380662306a36Sopenharmony_ci } 380762306a36Sopenharmony_ci } 380862306a36Sopenharmony_ci 380962306a36Sopenharmony_ci /* the rest */ 381062306a36Sopenharmony_ci nr_fails = 0; 381162306a36Sopenharmony_ci ata_for_each_link(link, ap, PMP_FIRST) { 381262306a36Sopenharmony_ci struct ata_eh_context *ehc = &link->eh_context; 381362306a36Sopenharmony_ci 381462306a36Sopenharmony_ci if (sata_pmp_attached(ap) && ata_is_host_link(link)) 381562306a36Sopenharmony_ci goto config_lpm; 381662306a36Sopenharmony_ci 381762306a36Sopenharmony_ci /* revalidate existing devices and attach new ones */ 381862306a36Sopenharmony_ci rc = ata_eh_revalidate_and_attach(link, &dev); 381962306a36Sopenharmony_ci if (rc) 382062306a36Sopenharmony_ci goto rest_fail; 382162306a36Sopenharmony_ci 382262306a36Sopenharmony_ci /* if PMP got attached, return, pmp EH will take care of it */ 382362306a36Sopenharmony_ci if (link->device->class == ATA_DEV_PMP) { 382462306a36Sopenharmony_ci ehc->i.action = 0; 382562306a36Sopenharmony_ci return 0; 382662306a36Sopenharmony_ci } 382762306a36Sopenharmony_ci 382862306a36Sopenharmony_ci /* configure transfer mode if necessary */ 382962306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_SETMODE) { 383062306a36Sopenharmony_ci rc = ata_set_mode(link, &dev); 383162306a36Sopenharmony_ci if (rc) 383262306a36Sopenharmony_ci goto rest_fail; 383362306a36Sopenharmony_ci ehc->i.flags &= ~ATA_EHI_SETMODE; 383462306a36Sopenharmony_ci } 383562306a36Sopenharmony_ci 383662306a36Sopenharmony_ci /* If reset has been issued, clear UA to avoid 383762306a36Sopenharmony_ci * disrupting the current users of the device. 383862306a36Sopenharmony_ci */ 383962306a36Sopenharmony_ci if (ehc->i.flags & ATA_EHI_DID_RESET) { 384062306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 384162306a36Sopenharmony_ci if (dev->class != ATA_DEV_ATAPI) 384262306a36Sopenharmony_ci continue; 384362306a36Sopenharmony_ci rc = atapi_eh_clear_ua(dev); 384462306a36Sopenharmony_ci if (rc) 384562306a36Sopenharmony_ci goto rest_fail; 384662306a36Sopenharmony_ci if (zpodd_dev_enabled(dev)) 384762306a36Sopenharmony_ci zpodd_post_poweron(dev); 384862306a36Sopenharmony_ci } 384962306a36Sopenharmony_ci } 385062306a36Sopenharmony_ci 385162306a36Sopenharmony_ci /* retry flush if necessary */ 385262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 385362306a36Sopenharmony_ci if (dev->class != ATA_DEV_ATA && 385462306a36Sopenharmony_ci dev->class != ATA_DEV_ZAC) 385562306a36Sopenharmony_ci continue; 385662306a36Sopenharmony_ci rc = ata_eh_maybe_retry_flush(dev); 385762306a36Sopenharmony_ci if (rc) 385862306a36Sopenharmony_ci goto rest_fail; 385962306a36Sopenharmony_ci } 386062306a36Sopenharmony_ci 386162306a36Sopenharmony_ci config_lpm: 386262306a36Sopenharmony_ci /* configure link power saving */ 386362306a36Sopenharmony_ci if (link->lpm_policy != ap->target_lpm_policy) { 386462306a36Sopenharmony_ci rc = ata_eh_set_lpm(link, ap->target_lpm_policy, &dev); 386562306a36Sopenharmony_ci if (rc) 386662306a36Sopenharmony_ci goto rest_fail; 386762306a36Sopenharmony_ci } 386862306a36Sopenharmony_ci 386962306a36Sopenharmony_ci /* this link is okay now */ 387062306a36Sopenharmony_ci ehc->i.flags = 0; 387162306a36Sopenharmony_ci continue; 387262306a36Sopenharmony_ci 387362306a36Sopenharmony_ci rest_fail: 387462306a36Sopenharmony_ci nr_fails++; 387562306a36Sopenharmony_ci if (dev) 387662306a36Sopenharmony_ci ata_eh_handle_dev_fail(dev, rc); 387762306a36Sopenharmony_ci 387862306a36Sopenharmony_ci if (ata_port_is_frozen(ap)) { 387962306a36Sopenharmony_ci /* PMP reset requires working host port. 388062306a36Sopenharmony_ci * Can't retry if it's frozen. 388162306a36Sopenharmony_ci */ 388262306a36Sopenharmony_ci if (sata_pmp_attached(ap)) 388362306a36Sopenharmony_ci goto out; 388462306a36Sopenharmony_ci break; 388562306a36Sopenharmony_ci } 388662306a36Sopenharmony_ci } 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci if (nr_fails) 388962306a36Sopenharmony_ci goto retry; 389062306a36Sopenharmony_ci 389162306a36Sopenharmony_ci out: 389262306a36Sopenharmony_ci if (rc && r_failed_link) 389362306a36Sopenharmony_ci *r_failed_link = link; 389462306a36Sopenharmony_ci 389562306a36Sopenharmony_ci return rc; 389662306a36Sopenharmony_ci} 389762306a36Sopenharmony_ci 389862306a36Sopenharmony_ci/** 389962306a36Sopenharmony_ci * ata_eh_finish - finish up EH 390062306a36Sopenharmony_ci * @ap: host port to finish EH for 390162306a36Sopenharmony_ci * 390262306a36Sopenharmony_ci * Recovery is complete. Clean up EH states and retry or finish 390362306a36Sopenharmony_ci * failed qcs. 390462306a36Sopenharmony_ci * 390562306a36Sopenharmony_ci * LOCKING: 390662306a36Sopenharmony_ci * None. 390762306a36Sopenharmony_ci */ 390862306a36Sopenharmony_civoid ata_eh_finish(struct ata_port *ap) 390962306a36Sopenharmony_ci{ 391062306a36Sopenharmony_ci struct ata_queued_cmd *qc; 391162306a36Sopenharmony_ci int tag; 391262306a36Sopenharmony_ci 391362306a36Sopenharmony_ci /* retry or finish qcs */ 391462306a36Sopenharmony_ci ata_qc_for_each_raw(ap, qc, tag) { 391562306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_EH)) 391662306a36Sopenharmony_ci continue; 391762306a36Sopenharmony_ci 391862306a36Sopenharmony_ci if (qc->err_mask) { 391962306a36Sopenharmony_ci /* FIXME: Once EH migration is complete, 392062306a36Sopenharmony_ci * generate sense data in this function, 392162306a36Sopenharmony_ci * considering both err_mask and tf. 392262306a36Sopenharmony_ci */ 392362306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_RETRY) { 392462306a36Sopenharmony_ci /* 392562306a36Sopenharmony_ci * Since qc->err_mask is set, ata_eh_qc_retry() 392662306a36Sopenharmony_ci * will not increment scmd->allowed, so upper 392762306a36Sopenharmony_ci * layer will only retry the command if it has 392862306a36Sopenharmony_ci * not already been retried too many times. 392962306a36Sopenharmony_ci */ 393062306a36Sopenharmony_ci ata_eh_qc_retry(qc); 393162306a36Sopenharmony_ci } else { 393262306a36Sopenharmony_ci ata_eh_qc_complete(qc); 393362306a36Sopenharmony_ci } 393462306a36Sopenharmony_ci } else { 393562306a36Sopenharmony_ci if (qc->flags & ATA_QCFLAG_SENSE_VALID || 393662306a36Sopenharmony_ci qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) { 393762306a36Sopenharmony_ci ata_eh_qc_complete(qc); 393862306a36Sopenharmony_ci } else { 393962306a36Sopenharmony_ci /* feed zero TF to sense generation */ 394062306a36Sopenharmony_ci memset(&qc->result_tf, 0, sizeof(qc->result_tf)); 394162306a36Sopenharmony_ci /* 394262306a36Sopenharmony_ci * Since qc->err_mask is not set, 394362306a36Sopenharmony_ci * ata_eh_qc_retry() will increment 394462306a36Sopenharmony_ci * scmd->allowed, so upper layer is guaranteed 394562306a36Sopenharmony_ci * to retry the command. 394662306a36Sopenharmony_ci */ 394762306a36Sopenharmony_ci ata_eh_qc_retry(qc); 394862306a36Sopenharmony_ci } 394962306a36Sopenharmony_ci } 395062306a36Sopenharmony_ci } 395162306a36Sopenharmony_ci 395262306a36Sopenharmony_ci /* make sure nr_active_links is zero after EH */ 395362306a36Sopenharmony_ci WARN_ON(ap->nr_active_links); 395462306a36Sopenharmony_ci ap->nr_active_links = 0; 395562306a36Sopenharmony_ci} 395662306a36Sopenharmony_ci 395762306a36Sopenharmony_ci/** 395862306a36Sopenharmony_ci * ata_do_eh - do standard error handling 395962306a36Sopenharmony_ci * @ap: host port to handle error for 396062306a36Sopenharmony_ci * 396162306a36Sopenharmony_ci * @prereset: prereset method (can be NULL) 396262306a36Sopenharmony_ci * @softreset: softreset method (can be NULL) 396362306a36Sopenharmony_ci * @hardreset: hardreset method (can be NULL) 396462306a36Sopenharmony_ci * @postreset: postreset method (can be NULL) 396562306a36Sopenharmony_ci * 396662306a36Sopenharmony_ci * Perform standard error handling sequence. 396762306a36Sopenharmony_ci * 396862306a36Sopenharmony_ci * LOCKING: 396962306a36Sopenharmony_ci * Kernel thread context (may sleep). 397062306a36Sopenharmony_ci */ 397162306a36Sopenharmony_civoid ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, 397262306a36Sopenharmony_ci ata_reset_fn_t softreset, ata_reset_fn_t hardreset, 397362306a36Sopenharmony_ci ata_postreset_fn_t postreset) 397462306a36Sopenharmony_ci{ 397562306a36Sopenharmony_ci struct ata_device *dev; 397662306a36Sopenharmony_ci int rc; 397762306a36Sopenharmony_ci 397862306a36Sopenharmony_ci ata_eh_autopsy(ap); 397962306a36Sopenharmony_ci ata_eh_report(ap); 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_ci rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset, 398262306a36Sopenharmony_ci NULL); 398362306a36Sopenharmony_ci if (rc) { 398462306a36Sopenharmony_ci ata_for_each_dev(dev, &ap->link, ALL) 398562306a36Sopenharmony_ci ata_dev_disable(dev); 398662306a36Sopenharmony_ci } 398762306a36Sopenharmony_ci 398862306a36Sopenharmony_ci ata_eh_finish(ap); 398962306a36Sopenharmony_ci} 399062306a36Sopenharmony_ci 399162306a36Sopenharmony_ci/** 399262306a36Sopenharmony_ci * ata_std_error_handler - standard error handler 399362306a36Sopenharmony_ci * @ap: host port to handle error for 399462306a36Sopenharmony_ci * 399562306a36Sopenharmony_ci * Standard error handler 399662306a36Sopenharmony_ci * 399762306a36Sopenharmony_ci * LOCKING: 399862306a36Sopenharmony_ci * Kernel thread context (may sleep). 399962306a36Sopenharmony_ci */ 400062306a36Sopenharmony_civoid ata_std_error_handler(struct ata_port *ap) 400162306a36Sopenharmony_ci{ 400262306a36Sopenharmony_ci struct ata_port_operations *ops = ap->ops; 400362306a36Sopenharmony_ci ata_reset_fn_t hardreset = ops->hardreset; 400462306a36Sopenharmony_ci 400562306a36Sopenharmony_ci /* ignore built-in hardreset if SCR access is not available */ 400662306a36Sopenharmony_ci if (hardreset == sata_std_hardreset && !sata_scr_valid(&ap->link)) 400762306a36Sopenharmony_ci hardreset = NULL; 400862306a36Sopenharmony_ci 400962306a36Sopenharmony_ci ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); 401062306a36Sopenharmony_ci} 401162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_std_error_handler); 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_ci#ifdef CONFIG_PM 401462306a36Sopenharmony_ci/** 401562306a36Sopenharmony_ci * ata_eh_handle_port_suspend - perform port suspend operation 401662306a36Sopenharmony_ci * @ap: port to suspend 401762306a36Sopenharmony_ci * 401862306a36Sopenharmony_ci * Suspend @ap. 401962306a36Sopenharmony_ci * 402062306a36Sopenharmony_ci * LOCKING: 402162306a36Sopenharmony_ci * Kernel thread context (may sleep). 402262306a36Sopenharmony_ci */ 402362306a36Sopenharmony_cistatic void ata_eh_handle_port_suspend(struct ata_port *ap) 402462306a36Sopenharmony_ci{ 402562306a36Sopenharmony_ci unsigned long flags; 402662306a36Sopenharmony_ci int rc = 0; 402762306a36Sopenharmony_ci struct ata_device *dev; 402862306a36Sopenharmony_ci struct ata_link *link; 402962306a36Sopenharmony_ci 403062306a36Sopenharmony_ci /* are we suspending? */ 403162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 403262306a36Sopenharmony_ci if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || 403362306a36Sopenharmony_ci ap->pm_mesg.event & PM_EVENT_RESUME) { 403462306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 403562306a36Sopenharmony_ci return; 403662306a36Sopenharmony_ci } 403762306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 403862306a36Sopenharmony_ci 403962306a36Sopenharmony_ci WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); 404062306a36Sopenharmony_ci 404162306a36Sopenharmony_ci /* Set all devices attached to the port in standby mode */ 404262306a36Sopenharmony_ci ata_for_each_link(link, ap, HOST_FIRST) { 404362306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) 404462306a36Sopenharmony_ci ata_dev_power_set_standby(dev); 404562306a36Sopenharmony_ci } 404662306a36Sopenharmony_ci 404762306a36Sopenharmony_ci /* 404862306a36Sopenharmony_ci * If we have a ZPODD attached, check its zero 404962306a36Sopenharmony_ci * power ready status before the port is frozen. 405062306a36Sopenharmony_ci * Only needed for runtime suspend. 405162306a36Sopenharmony_ci */ 405262306a36Sopenharmony_ci if (PMSG_IS_AUTO(ap->pm_mesg)) { 405362306a36Sopenharmony_ci ata_for_each_dev(dev, &ap->link, ENABLED) { 405462306a36Sopenharmony_ci if (zpodd_dev_enabled(dev)) 405562306a36Sopenharmony_ci zpodd_on_suspend(dev); 405662306a36Sopenharmony_ci } 405762306a36Sopenharmony_ci } 405862306a36Sopenharmony_ci 405962306a36Sopenharmony_ci /* suspend */ 406062306a36Sopenharmony_ci ata_eh_freeze_port(ap); 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_ci if (ap->ops->port_suspend) 406362306a36Sopenharmony_ci rc = ap->ops->port_suspend(ap, ap->pm_mesg); 406462306a36Sopenharmony_ci 406562306a36Sopenharmony_ci ata_acpi_set_state(ap, ap->pm_mesg); 406662306a36Sopenharmony_ci 406762306a36Sopenharmony_ci /* update the flags */ 406862306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_PM_PENDING; 407162306a36Sopenharmony_ci if (rc == 0) 407262306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_SUSPENDED; 407362306a36Sopenharmony_ci else if (ata_port_is_frozen(ap)) 407462306a36Sopenharmony_ci ata_port_schedule_eh(ap); 407562306a36Sopenharmony_ci 407662306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 407762306a36Sopenharmony_ci 407862306a36Sopenharmony_ci return; 407962306a36Sopenharmony_ci} 408062306a36Sopenharmony_ci 408162306a36Sopenharmony_ci/** 408262306a36Sopenharmony_ci * ata_eh_handle_port_resume - perform port resume operation 408362306a36Sopenharmony_ci * @ap: port to resume 408462306a36Sopenharmony_ci * 408562306a36Sopenharmony_ci * Resume @ap. 408662306a36Sopenharmony_ci * 408762306a36Sopenharmony_ci * LOCKING: 408862306a36Sopenharmony_ci * Kernel thread context (may sleep). 408962306a36Sopenharmony_ci */ 409062306a36Sopenharmony_cistatic void ata_eh_handle_port_resume(struct ata_port *ap) 409162306a36Sopenharmony_ci{ 409262306a36Sopenharmony_ci struct ata_link *link; 409362306a36Sopenharmony_ci struct ata_device *dev; 409462306a36Sopenharmony_ci unsigned long flags; 409562306a36Sopenharmony_ci 409662306a36Sopenharmony_ci /* are we resuming? */ 409762306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 409862306a36Sopenharmony_ci if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || 409962306a36Sopenharmony_ci !(ap->pm_mesg.event & PM_EVENT_RESUME)) { 410062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 410162306a36Sopenharmony_ci return; 410262306a36Sopenharmony_ci } 410362306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 410462306a36Sopenharmony_ci 410562306a36Sopenharmony_ci WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); 410662306a36Sopenharmony_ci 410762306a36Sopenharmony_ci /* 410862306a36Sopenharmony_ci * Error timestamps are in jiffies which doesn't run while 410962306a36Sopenharmony_ci * suspended and PHY events during resume isn't too uncommon. 411062306a36Sopenharmony_ci * When the two are combined, it can lead to unnecessary speed 411162306a36Sopenharmony_ci * downs if the machine is suspended and resumed repeatedly. 411262306a36Sopenharmony_ci * Clear error history. 411362306a36Sopenharmony_ci */ 411462306a36Sopenharmony_ci ata_for_each_link(link, ap, HOST_FIRST) 411562306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) 411662306a36Sopenharmony_ci ata_ering_clear(&dev->ering); 411762306a36Sopenharmony_ci 411862306a36Sopenharmony_ci ata_acpi_set_state(ap, ap->pm_mesg); 411962306a36Sopenharmony_ci 412062306a36Sopenharmony_ci if (ap->ops->port_resume) 412162306a36Sopenharmony_ci ap->ops->port_resume(ap); 412262306a36Sopenharmony_ci 412362306a36Sopenharmony_ci /* tell ACPI that we're resuming */ 412462306a36Sopenharmony_ci ata_acpi_on_resume(ap); 412562306a36Sopenharmony_ci 412662306a36Sopenharmony_ci /* update the flags */ 412762306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 412862306a36Sopenharmony_ci ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); 412962306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_RESUMING; 413062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 413162306a36Sopenharmony_ci} 413262306a36Sopenharmony_ci#endif /* CONFIG_PM */ 4133