linux/include/scsi/sas_ata.h
John Garry 4411292267 scsi: libsas: Add sas_ata_device_link_abort()
Similar to how AHCI handles NCQ errors in ahci_error_intr() ->
ata_port_abort() -> ata_do_link_abort(), add an NCQ error handler for LLDDs
to call to initiate a link abort.

This will mark all outstanding QCs as failed and kick-off EH.

Note:

A "force reset" argument is added for drivers which require the ATA error
handling to always reset the device.

A driver may require this feature for when SATA device per-SCSI cmnd
resources are only released during reset for ATA EH. As such, we need an
option to force reset to be done, regardless of what any EH autopsy
decides.

The SATA device FIS fields are set to indicate a device error from
ata_eh_analyze_tf().

Suggested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Suggested-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1665998435-199946-2-git-send-email-john.garry@huawei.com
Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Tested-by: Niklas Cassel <niklas.cassel@wdc.com> # pm80xx
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2022-10-18 02:37:45 +00:00

110 lines
2.6 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Support for SATA devices on Serial Attached SCSI (SAS) controllers
*
* Copyright (C) 2006 IBM Corporation
*
* Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation
*/
#ifndef _SAS_ATA_H_
#define _SAS_ATA_H_
#include <linux/libata.h>
#include <scsi/libsas.h>
#ifdef CONFIG_SCSI_SAS_ATA
static inline int dev_is_sata(struct domain_device *dev)
{
return dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM ||
dev->dev_type == SAS_SATA_PM_PORT || dev->dev_type == SAS_SATA_PENDING;
}
int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
int sas_ata_init(struct domain_device *dev);
void sas_ata_task_abort(struct sas_task *task);
void sas_ata_strategy_handler(struct Scsi_Host *shost);
void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q);
void sas_ata_schedule_reset(struct domain_device *dev);
void sas_ata_wait_eh(struct domain_device *dev);
void sas_probe_sata(struct asd_sas_port *port);
void sas_suspend_sata(struct asd_sas_port *port);
void sas_resume_sata(struct asd_sas_port *port);
void sas_ata_end_eh(struct ata_port *ap);
void sas_ata_device_link_abort(struct domain_device *dev, bool force_reset);
int sas_execute_ata_cmd(struct domain_device *device, u8 *fis,
int force_phy_id);
int sas_ata_wait_after_reset(struct domain_device *dev, unsigned long deadline);
#else
static inline int dev_is_sata(struct domain_device *dev)
{
return 0;
}
static inline int sas_ata_init(struct domain_device *dev)
{
return 0;
}
static inline void sas_ata_task_abort(struct sas_task *task)
{
}
static inline void sas_ata_strategy_handler(struct Scsi_Host *shost)
{
}
static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q)
{
}
static inline void sas_ata_schedule_reset(struct domain_device *dev)
{
}
static inline void sas_ata_wait_eh(struct domain_device *dev)
{
}
static inline void sas_probe_sata(struct asd_sas_port *port)
{
}
static inline void sas_suspend_sata(struct asd_sas_port *port)
{
}
static inline void sas_resume_sata(struct asd_sas_port *port)
{
}
static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
{
return 0;
}
static inline void sas_ata_end_eh(struct ata_port *ap)
{
}
static inline void sas_ata_device_link_abort(struct domain_device *dev,
bool force_reset)
{
}
static inline int sas_execute_ata_cmd(struct domain_device *device, u8 *fis,
int force_phy_id)
{
return 0;
}
static inline int sas_ata_wait_after_reset(struct domain_device *dev,
unsigned long deadline)
{
return -ETIMEDOUT;
}
#endif
#endif /* _SAS_ATA_H_ */