1

ATA changes for 6.7-rc1

- Modify the AHCI driver to print the link power management policy used
    on scan, to help with debugging issues (Niklas).
 
  - Add support for the ASM2116 series adapters to the AHCI driver
    (Szuying).
 
  - Prepare libata for the coming gcc and Clang __counted_by attribute
    (Kees).
 
  - Following the recent estensive fixing of libata suspend/resume
    handling, several patches further cleanup and improve disk power state
    management (from me).
 
  - Reduce the verbosity of some error messages for non-fatal temporary
    errors, e.g. slow response to device reset when scanning a port, and
    warning messages that are in fact normal, e.g. disabling a device
    on suspend or when removing it (from me).
 
  - Cleanup DMA helper functions (from me).
 
  - Fix sata_mv drive handling of potential errors durring probe (Ma).
 
  - Cleanup the xgene and imx drivers using the functions
    of_device_get_match_data() and device_get_match_data() (Rob).
 
  - Improve the tegra driver device tree (Rob).
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSRPv8tYSvhwAzJdzjdoc3SxdoYdgUCZT9PtwAKCRDdoc3SxdoY
 diCGAQCbSOB3PCpsm1cCMevZeEbt+zUSx+sj6twR12RohtQK6wEA1rEytQllZyqa
 Pk/jIH2UYZaf+lVuV3Vbey4rwDYXTQs=
 =V53T
 -----END PGP SIGNATURE-----

Merge tag 'ata-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata

Pull ATA updates from Damien Le Moal:

 - Modify the AHCI driver to print the link power management policy used
   on scan, to help with debugging issues (Niklas)

 - Add support for the ASM2116 series adapters to the AHCI driver
   (Szuying)

 - Prepare libata for the coming gcc and Clang __counted_by attribute
   (Kees)

 - Following the recent estensive fixing of libata suspend/resume
   handling, several patches further cleanup and improve disk power
   state management (me)

 - Reduce the verbosity of some error messages for non-fatal temporary
   errors, e.g. slow response to device reset when scanning a port, and
   warning messages that are in fact normal, e.g. disabling a device on
   suspend or when removing it (me)

 - Cleanup DMA helper functions (me)

 - Fix sata_mv drive handling of potential errors durring probe (Ma)

 - Cleanup the xgene and imx drivers using the functions
   of_device_get_match_data() and device_get_match_data() (Rob)

 - Improve the tegra driver device tree (Rob)

* tag 'ata-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata: (22 commits)
  dt-bindings: ata: tegra: Disallow undefined properties
  ata: libata-core: Improve ata_dev_power_set_active()
  ata: libata-eh: Spinup disk on resume after revalidation
  ata: imx: Use device_get_match_data()
  ata: xgene: Use of_device_get_match_data()
  ata: sata_mv: aspeed: fix value check in mv_platform_probe()
  ata: ahci: Add Intel Alder Lake-P AHCI controller to low power chipsets list
  ata: libata: Cleanup inline DMA helper functions
  ata: libata-eh: Reduce "disable device" message verbosity
  ata: libata-eh: Improve reset error messages
  ata: libata-sata: Improve ata_sas_slave_configure()
  ata: libata-core: Do not resume runtime suspended ports
  ata: libata-core: Do not poweroff runtime suspended ports
  ata: libata-core: Remove ata_port_resume_async()
  ata: libata-core: Remove ata_port_suspend_async()
  ata: libata-core: Detach a port devices on shutdown
  ata: libata-core: Synchronize ata_port_detach() with hotplug
  ata: libata-scsi: Cleanup ata_scsi_start_stop_xlat()
  scsi: Remove scsi device no_start_on_resume flag
  ata: libata: Annotate struct ata_cpr_log with __counted_by
  ...
This commit is contained in:
Linus Torvalds 2023-11-01 12:50:12 -10:00
commit 39714efc23
16 changed files with 201 additions and 185 deletions

View File

@ -151,7 +151,7 @@ allOf:
- interconnects
- power-domains
additionalProperties: true
additionalProperties: false
examples:
- |

View File

@ -423,6 +423,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */
{ PCI_VDEVICE(INTEL, 0x7ae2), board_ahci_low_power }, /* Alder Lake-P AHCI */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@ -604,6 +605,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */
{ PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */
{ PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci }, /* ASM1062+JMB575 */
{ PCI_VDEVICE(ASMEDIA, 0x1062), board_ahci }, /* ASM1062A */
{ PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */
{ PCI_VDEVICE(ASMEDIA, 0x1164), board_ahci }, /* ASM1164 */
{ PCI_VDEVICE(ASMEDIA, 0x1165), board_ahci }, /* ASM1165 */
{ PCI_VDEVICE(ASMEDIA, 0x1166), board_ahci }, /* ASM1166 */
/*
* Samsung SSDs found on some macbooks. NCQ times out if MSI is

View File

@ -9,10 +9,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/ahci_platform.h>
#include <linux/gpio/consumer.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/libata.h>
@ -1050,16 +1051,11 @@ static int imx8_sata_probe(struct device *dev, struct imx_ahci_priv *imxpriv)
static int imx_ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
struct ahci_host_priv *hpriv;
struct imx_ahci_priv *imxpriv;
unsigned int reg_val;
int ret;
of_id = of_match_device(imx_ahci_of_match, dev);
if (!of_id)
return -EINVAL;
imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
if (!imxpriv)
return -ENOMEM;
@ -1067,7 +1063,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
imxpriv->ahci_pdev = pdev;
imxpriv->no_device = false;
imxpriv->first_time = true;
imxpriv->type = (unsigned long)of_id->data;
imxpriv->type = (enum ahci_imx_type)device_get_match_data(dev);
imxpriv->sata_clk = devm_clk_get(dev, "sata");
if (IS_ERR(imxpriv->sata_clk)) {

View File

@ -13,9 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ahci_platform.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include "ahci.h"
@ -735,7 +733,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct xgene_ahci_context *ctx;
struct resource *res;
const struct of_device_id *of_devid;
enum xgene_ahci_version version = XGENE_AHCI_V1;
const struct ata_port_info *ppi[] = { &xgene_ahci_v1_port_info,
&xgene_ahci_v2_port_info };
@ -778,10 +775,8 @@ static int xgene_ahci_probe(struct platform_device *pdev)
ctx->csr_mux = csr;
}
of_devid = of_match_device(xgene_ahci_of_match, dev);
if (of_devid) {
if (of_devid->data)
version = (unsigned long) of_devid->data;
if (dev->of_node) {
version = (enum xgene_ahci_version)of_device_get_match_data(dev);
}
#ifdef CONFIG_ACPI
else {

View File

@ -2730,7 +2730,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host,
if (rc)
return rc;
ata_port_desc(host->ports[i], "irq %d", irq);
ata_port_desc_misc(host->ports[i], irq);
}
return ata_host_register(host, sht);

View File

@ -1972,6 +1972,35 @@ retry:
return rc;
}
bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf,
bool set_active)
{
/* Only applies to ATA and ZAC devices */
if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
return false;
ata_tf_init(dev, tf);
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf->protocol = ATA_PROT_NODATA;
if (set_active) {
/* VERIFY for 1 sector at lba=0 */
tf->command = ATA_CMD_VERIFY;
tf->nsect = 1;
if (dev->flags & ATA_DFLAG_LBA) {
tf->flags |= ATA_TFLAG_LBA;
tf->device |= ATA_LBA;
} else {
/* CHS */
tf->lbal = 0x1; /* sect */
}
} else {
tf->command = ATA_CMD_STANDBYNOW1;
}
return true;
}
/**
* ata_dev_power_set_standby - Set a device power mode to standby
* @dev: target device
@ -1988,10 +2017,6 @@ void ata_dev_power_set_standby(struct ata_device *dev)
struct ata_taskfile tf;
unsigned int err_mask;
/* Issue STANDBY IMMEDIATE command only if supported by the device */
if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
return;
/*
* Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5)
* causing some drives to spin up and down again. For these, do nothing
@ -2005,10 +2030,9 @@ void ata_dev_power_set_standby(struct ata_device *dev)
system_entering_hibernation())
return;
ata_tf_init(dev, &tf);
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol = ATA_PROT_NODATA;
tf.command = ATA_CMD_STANDBYNOW1;
/* Issue STANDBY IMMEDIATE command only if supported by the device */
if (!ata_dev_power_init_tf(dev, &tf, false))
return;
ata_dev_notice(dev, "Entering standby power mode\n");
@ -2018,6 +2042,33 @@ void ata_dev_power_set_standby(struct ata_device *dev)
err_mask);
}
static bool ata_dev_power_is_active(struct ata_device *dev)
{
struct ata_taskfile tf;
unsigned int err_mask;
ata_tf_init(dev, &tf);
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol = ATA_PROT_NODATA;
tf.command = ATA_CMD_CHK_POWER;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
if (err_mask) {
ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
err_mask);
/*
* Assume we are in standby mode so that we always force a
* spinup in ata_dev_power_set_active().
*/
return false;
}
ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
/* Active or idle */
return tf.nsect == 0xff;
}
/**
* ata_dev_power_set_active - Set a device power mode to active
* @dev: target device
@ -2038,21 +2089,15 @@ void ata_dev_power_set_active(struct ata_device *dev)
* Issue READ VERIFY SECTORS command for 1 sector at lba=0 only
* if supported by the device.
*/
if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
if (!ata_dev_power_init_tf(dev, &tf, true))
return;
ata_tf_init(dev, &tf);
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol = ATA_PROT_NODATA;
tf.command = ATA_CMD_VERIFY;
tf.nsect = 1;
if (dev->flags & ATA_DFLAG_LBA) {
tf.flags |= ATA_TFLAG_LBA;
tf.device |= ATA_LBA;
} else {
/* CHS */
tf.lbal = 0x1; /* sect */
}
/*
* Check the device power state & condition and force a spinup with
* VERIFY command only if the drive is not already ACTIVE or IDLE.
*/
if (ata_dev_power_is_active(dev))
return;
ata_dev_notice(dev, "Entering active power mode\n");
@ -5155,41 +5200,29 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
ata_port_wait_eh(ap);
}
static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg,
bool async)
{
/*
* On some hardware, device fails to respond after spun down for suspend. As
* the device won't be used before being resumed, we don't need to touch the
* device. Ask EH to skip the usual stuff and proceed directly to suspend.
* We are about to suspend the port, so we do not care about
* scsi_rescan_device() calls scheduled by previous resume operations.
* The next resume will schedule the rescan again. So cancel any rescan
* that is not done yet.
*/
cancel_delayed_work_sync(&ap->scsi_rescan_task);
/*
* On some hardware, device fails to respond after spun down for
* suspend. As the device will not be used until being resumed, we
* do not need to touch the device. Ask EH to skip the usual stuff
* and proceed directly to suspend.
*
* http://thread.gmane.org/gmane.linux.ide/46764
*/
static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET
| ATA_EHI_NO_AUTOPSY
| ATA_EHI_NO_RECOVERY;
static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg)
{
/*
* We are about to suspend the port, so we do not care about
* scsi_rescan_device() calls scheduled by previous resume operations.
* The next resume will schedule the rescan again. So cancel any rescan
* that is not done yet.
*/
cancel_delayed_work_sync(&ap->scsi_rescan_task);
ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false);
}
static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg)
{
/*
* We are about to suspend the port, so we do not care about
* scsi_rescan_device() calls scheduled by previous resume operations.
* The next resume will schedule the rescan again. So cancel any rescan
* that is not done yet.
*/
cancel_delayed_work_sync(&ap->scsi_rescan_task);
ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true);
ata_port_request_pm(ap, mesg, 0,
ATA_EHI_QUIET | ATA_EHI_NO_AUTOPSY |
ATA_EHI_NO_RECOVERY,
async);
}
static int ata_port_pm_suspend(struct device *dev)
@ -5199,7 +5232,7 @@ static int ata_port_pm_suspend(struct device *dev)
if (pm_runtime_suspended(dev))
return 0;
ata_port_suspend(ap, PMSG_SUSPEND);
ata_port_suspend(ap, PMSG_SUSPEND, false);
return 0;
}
@ -5210,35 +5243,29 @@ static int ata_port_pm_freeze(struct device *dev)
if (pm_runtime_suspended(dev))
return 0;
ata_port_suspend(ap, PMSG_FREEZE);
ata_port_suspend(ap, PMSG_FREEZE, false);
return 0;
}
static int ata_port_pm_poweroff(struct device *dev)
{
ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE);
if (!pm_runtime_suspended(dev))
ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE, false);
return 0;
}
static const unsigned int ata_port_resume_ehi = ATA_EHI_NO_AUTOPSY
| ATA_EHI_QUIET;
static void ata_port_resume(struct ata_port *ap, pm_message_t mesg)
static void ata_port_resume(struct ata_port *ap, pm_message_t mesg,
bool async)
{
ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, false);
}
static void ata_port_resume_async(struct ata_port *ap, pm_message_t mesg)
{
ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, true);
ata_port_request_pm(ap, mesg, ATA_EH_RESET,
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET,
async);
}
static int ata_port_pm_resume(struct device *dev)
{
ata_port_resume_async(to_ata_port(dev), PMSG_RESUME);
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
if (!pm_runtime_suspended(dev))
ata_port_resume(to_ata_port(dev), PMSG_RESUME, true);
return 0;
}
@ -5268,13 +5295,13 @@ static int ata_port_runtime_idle(struct device *dev)
static int ata_port_runtime_suspend(struct device *dev)
{
ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND);
ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND, false);
return 0;
}
static int ata_port_runtime_resume(struct device *dev)
{
ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME);
ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME, false);
return 0;
}
@ -5298,13 +5325,13 @@ static const struct dev_pm_ops ata_port_pm_ops = {
*/
void ata_sas_port_suspend(struct ata_port *ap)
{
ata_port_suspend_async(ap, PMSG_SUSPEND);
ata_port_suspend(ap, PMSG_SUSPEND, true);
}
EXPORT_SYMBOL_GPL(ata_sas_port_suspend);
void ata_sas_port_resume(struct ata_port *ap)
{
ata_port_resume_async(ap, PMSG_RESUME);
ata_port_resume(ap, PMSG_RESUME, true);
}
EXPORT_SYMBOL_GPL(ata_sas_port_resume);
@ -6026,7 +6053,7 @@ int ata_host_activate(struct ata_host *host, int irq,
return rc;
for (i = 0; i < host->n_ports; i++)
ata_port_desc(host->ports[i], "irq %d", irq);
ata_port_desc_misc(host->ports[i], irq);
rc = ata_host_register(host, sht);
/* if failed, just free the IRQ and leave ports alone */
@ -6054,6 +6081,9 @@ static void ata_port_detach(struct ata_port *ap)
struct ata_link *link;
struct ata_device *dev;
/* Ensure ata_port probe has completed */
async_synchronize_cookie(ap->cookie + 1);
/* Wait for any ongoing EH */
ata_port_wait_eh(ap);
@ -6118,11 +6148,8 @@ void ata_host_detach(struct ata_host *host)
{
int i;
for (i = 0; i < host->n_ports; i++) {
/* Ensure ata_port probe has completed */
async_synchronize_cookie(host->ports[i]->cookie + 1);
for (i = 0; i < host->n_ports; i++)
ata_port_detach(host->ports[i]);
}
/* the host is dead now, dissociate ACPI */
ata_acpi_dissociate(host);
@ -6153,10 +6180,24 @@ EXPORT_SYMBOL_GPL(ata_pci_remove_one);
void ata_pci_shutdown_one(struct pci_dev *pdev)
{
struct ata_host *host = pci_get_drvdata(pdev);
struct ata_port *ap;
unsigned long flags;
int i;
/* Tell EH to disable all devices */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
ap = host->ports[i];
spin_lock_irqsave(ap->lock, flags);
ap->pflags |= ATA_PFLAG_UNLOADING;
ata_port_schedule_eh(ap);
spin_unlock_irqrestore(ap->lock, flags);
}
for (i = 0; i < host->n_ports; i++) {
ap = host->ports[i];
/* Wait for EH to complete before freezing the port */
ata_port_wait_eh(ap);
ap->pflags |= ATA_PFLAG_FROZEN;

View File

@ -494,6 +494,18 @@ void ata_eh_release(struct ata_port *ap)
mutex_unlock(&ap->host->eh_mutex);
}
static void ata_eh_dev_disable(struct ata_device *dev)
{
ata_acpi_on_disable(dev);
ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
dev->class++;
/* From now till the next successful probe, ering is used to
* track probe failures. Clear accumulated device error info.
*/
ata_ering_clear(&dev->ering);
}
static void ata_eh_unload(struct ata_port *ap)
{
struct ata_link *link;
@ -517,8 +529,8 @@ static void ata_eh_unload(struct ata_port *ap)
*/
ata_for_each_link(link, ap, PMP_FIRST) {
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
ata_for_each_dev(dev, link, ALL)
ata_dev_disable(dev);
ata_for_each_dev(dev, link, ENABLED)
ata_eh_dev_disable(dev);
}
/* freeze and set UNLOADED */
@ -1211,14 +1223,8 @@ void ata_dev_disable(struct ata_device *dev)
return;
ata_dev_warn(dev, "disable device\n");
ata_acpi_on_disable(dev);
ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
dev->class++;
/* From now till the next successful probe, ering is used to
* track probe failures. Clear accumulated device error info.
*/
ata_ering_clear(&dev->ering);
ata_eh_dev_disable(dev);
}
EXPORT_SYMBOL_GPL(ata_dev_disable);
@ -1240,12 +1246,12 @@ void ata_eh_detach_dev(struct ata_device *dev)
/*
* If the device is still enabled, transition it to standby power mode
* (i.e. spin down HDDs).
* (i.e. spin down HDDs) and disable it.
*/
if (ata_dev_enabled(dev))
if (ata_dev_enabled(dev)) {
ata_dev_power_set_standby(dev);
ata_dev_disable(dev);
ata_eh_dev_disable(dev);
}
spin_lock_irqsave(ap->lock, flags);
@ -2909,6 +2915,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
if (ata_is_host_link(link))
ata_eh_thaw_port(ap);
ata_link_warn(link, "%s failed\n",
reset == hardreset ? "hardreset" : "softreset");
goto out;
}
@ -3043,15 +3051,6 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
if (ehc->i.flags & ATA_EHI_DID_RESET)
readid_flags |= ATA_READID_POSTRESET;
/*
* When resuming, before executing any command, make sure to
* transition the device to the active power mode.
*/
if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) {
ata_dev_power_set_active(dev);
ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
}
if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
WARN_ON(dev->class == ATA_DEV_PMP);
@ -3848,6 +3847,17 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
}
}
/*
* Make sure to transition devices to the active power mode
* if needed (e.g. if we were scheduled on system resume).
*/
ata_for_each_dev(dev, link, ENABLED) {
if (ehc->i.dev_action[dev->devno] & ATA_EH_SET_ACTIVE) {
ata_dev_power_set_active(dev);
ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
}
}
/* retry flush if necessary */
ata_for_each_dev(dev, link, ALL) {
if (dev->class != ATA_DEV_ATA &&

View File

@ -621,7 +621,6 @@ int sata_link_hardreset(struct ata_link *link, const unsigned int *timing,
/* online is set iff link is online && reset succeeded */
if (online)
*online = false;
ata_link_err(link, "COMRESET failed (errno=%d)\n", rc);
}
return rc;
}
@ -1182,8 +1181,8 @@ EXPORT_SYMBOL_GPL(ata_sas_tport_delete);
int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap)
{
ata_scsi_sdev_config(sdev);
ata_scsi_dev_config(sdev, ap->link.device);
return 0;
return ata_scsi_dev_config(sdev, ap->link.device);
}
EXPORT_SYMBOL_GPL(ata_sas_slave_configure);

View File

@ -1203,7 +1203,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
const u8 *cdb = scmd->cmnd;
u16 fp;
u8 bp = 0xff;
@ -1213,54 +1212,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
goto invalid_fld;
}
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf->protocol = ATA_PROT_NODATA;
if (cdb[1] & 0x1) {
; /* ignore IMMED bit, violates sat-r05 */
}
/* LOEJ bit set not supported */
if (cdb[4] & 0x2) {
fp = 4;
bp = 1;
goto invalid_fld; /* LOEJ bit set not supported */
goto invalid_fld;
}
/* Power conditions not supported */
if (((cdb[4] >> 4) & 0xf) != 0) {
fp = 4;
bp = 3;
goto invalid_fld; /* power conditions not supported */
goto invalid_fld;
}
if (cdb[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
if (qc->dev->flags & ATA_DFLAG_LBA) {
tf->flags |= ATA_TFLAG_LBA;
tf->lbah = 0x0;
tf->lbam = 0x0;
tf->lbal = 0x0;
tf->device |= ATA_LBA;
} else {
/* CHS */
tf->lbal = 0x1; /* sect */
tf->lbam = 0x0; /* cyl low */
tf->lbah = 0x0; /* cyl high */
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
/* Some odd clown BIOSen issue spindown on power off (ACPI S4
* or S5) causing some drives to spin up and down again.
*/
if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
system_state == SYSTEM_POWER_OFF)
goto skip;
if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
system_entering_hibernation())
goto skip;
/* Issue ATA STANDBY IMMEDIATE command */
tf->command = ATA_CMD_STANDBYNOW1;
/* Ignore IMMED bit (cdb[1] & 0x1), violates sat-r05 */
if (!ata_dev_power_init_tf(qc->dev, &qc->tf, cdb[4] & 0x1)) {
ata_scsi_set_sense(qc->dev, scmd, ABORTED_COMMAND, 0, 0);
return 1;
}
/*
@ -1275,12 +1244,8 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
invalid_fld:
ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
return 1;
skip:
scmd->result = SAM_STAT_GOOD;
return 1;
}
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile

View File

@ -2316,7 +2316,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
for (i = 0; i < 2; i++) {
if (ata_port_is_dummy(host->ports[i]))
continue;
ata_port_desc(host->ports[i], "irq %d", pdev->irq);
ata_port_desc_misc(host->ports[i], pdev->irq);
}
} else if (legacy_mode) {
if (!ata_port_is_dummy(host->ports[0])) {
@ -2326,7 +2326,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
if (rc)
goto out;
ata_port_desc(host->ports[0], "irq %d",
ata_port_desc_misc(host->ports[0],
ATA_PRIMARY_IRQ(pdev));
}
@ -2337,7 +2337,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
if (rc)
goto out;
ata_port_desc(host->ports[1], "irq %d",
ata_port_desc_misc(host->ports[1],
ATA_SECONDARY_IRQ(pdev));
}
}

View File

@ -62,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
unsigned int readid_flags);
extern int ata_dev_configure(struct ata_device *dev);
extern bool ata_dev_power_init_tf(struct ata_device *dev,
struct ata_taskfile *tf, bool set_active);
extern void ata_dev_power_set_standby(struct ata_device *dev);
extern void ata_dev_power_set_active(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);

View File

@ -212,7 +212,7 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
ata_port_desc(ap, "irq %d", irq[i]);
ata_port_desc_misc(ap, irq[i]);
}
return ata_host_register(host, &cs5520_sht);

View File

@ -4123,10 +4123,13 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->base -= SATAHC0_REG_BASE;
hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk))
if (IS_ERR(hpriv->clk)) {
dev_notice(&pdev->dev, "cannot get optional clkdev\n");
else
clk_prepare_enable(hpriv->clk);
} else {
rc = clk_prepare_enable(hpriv->clk);
if (rc)
goto err;
}
for (port = 0; port < n_ports; port++) {
char port_number[16];

View File

@ -3928,7 +3928,7 @@ static int sd_suspend_runtime(struct device *dev)
static int sd_resume(struct device *dev, bool runtime)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
int ret = 0;
int ret;
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
return 0;
@ -3938,11 +3938,8 @@ static int sd_resume(struct device *dev, bool runtime)
return 0;
}
if (!sdkp->device->no_start_on_resume) {
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1);
}
if (!ret) {
opal_unlock_from_suspend(sdkp->opal_dev);
sdkp->suspended = false;

View File

@ -656,7 +656,7 @@ struct ata_cpr {
struct ata_cpr_log {
u8 nr_cpr;
struct ata_cpr cpr[];
struct ata_cpr cpr[] __counted_by(nr_cpr);
};
struct ata_device {
@ -1561,6 +1561,11 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...);
extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
const char *name);
#endif
static inline void ata_port_desc_misc(struct ata_port *ap, int irq)
{
ata_port_desc(ap, "irq %d", irq);
ata_port_desc(ap, "lpm-pol %d", ap->target_lpm_policy);
}
static inline bool ata_tag_internal(unsigned int tag)
{
@ -1881,23 +1886,21 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
change in future hardware and specs, secondly 0xFF means 'no DMA' but is
> UDMA_0. Dyma ddreigiau */
static inline int ata_using_mwdma(struct ata_device *adev)
static inline bool ata_using_mwdma(struct ata_device *adev)
{
if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
return 1;
return 0;
return adev->dma_mode >= XFER_MW_DMA_0 &&
adev->dma_mode <= XFER_MW_DMA_4;
}
static inline int ata_using_udma(struct ata_device *adev)
static inline bool ata_using_udma(struct ata_device *adev)
{
if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
return 1;
return 0;
return adev->dma_mode >= XFER_UDMA_0 &&
adev->dma_mode <= XFER_UDMA_7;
}
static inline int ata_dma_enabled(struct ata_device *adev)
static inline bool ata_dma_enabled(struct ata_device *adev)
{
return (adev->dma_mode == 0xFF ? 0 : 1);
return adev->dma_mode != 0xFF;
}
/**************************************************************************

View File

@ -213,7 +213,6 @@ struct scsi_device {
unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
unsigned no_start_on_add:1; /* do not issue start on add */
unsigned allow_restart:1; /* issue START_UNIT in error handler */
unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */
unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */
unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
unsigned select_no_atn:1;