Start separating SATA specific code from libata-eh.c: * move sata_async_notification() to libata-eh-sata.c: * cover sata_async_notification() with CONFIG_SATA_HOST ifdef in <linux/libata.h> * include libata-eh-sata.c in the build when CONFIG_SATA_HOST=y Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 16889 18 0 16907 420b drivers/ata/libata-eh.o after: 16810 18 0 16828 41bc drivers/ata/libata-eh.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@xxxxxxxxxxx> --- drivers/ata/Makefile | 3 +- drivers/ata/libata-eh-sata.c | 85 ++++++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 74 ------------------------------- include/linux/libata.h | 8 +++- 4 files changed, 94 insertions(+), 76 deletions(-) create mode 100644 drivers/ata/libata-eh-sata.c diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d6fb3d4a2ac5..6bdbbcce8fef 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -123,7 +123,8 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o libata-y := libata-core.o libata-scsi.o libata-eh.o \ libata-transport.o libata-trace.o -libata-$(CONFIG_SATA_HOST) += libata-core-sata.o libata-scsi-sata.o +libata-$(CONFIG_SATA_HOST) += libata-core-sata.o libata-scsi-sata.o \ + libata-eh-sata.o libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o diff --git a/drivers/ata/libata-eh-sata.c b/drivers/ata/libata-eh-sata.c new file mode 100644 index 000000000000..4b6dc715629a --- /dev/null +++ b/drivers/ata/libata-eh-sata.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * libata-eh.c - SATA specific part of libata error handling + * + * Copyright 2006 Tejun Heo <htejun@xxxxxxxxx> + */ + +#include <linux/kernel.h> +#include <linux/libata.h> + +#include "libata.h" + +/** + * sata_async_notification - SATA async notification handler + * @ap: ATA port where async notification is received + * + * Handler to be called when async notification via SDB FIS is + * received. This function schedules EH if necessary. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * 1 if EH is scheduled, 0 otherwise. + */ +int sata_async_notification(struct ata_port *ap) +{ + u32 sntf; + int rc; + + if (!(ap->flags & ATA_FLAG_AN)) + return 0; + + rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf); + if (rc == 0) + sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); + + if (!sata_pmp_attached(ap) || rc) { + /* PMP is not attached or SNTF is not available */ + if (!sata_pmp_attached(ap)) { + /* PMP is not attached. Check whether ATAPI + * AN is configured. If so, notify media + * change. + */ + struct ata_device *dev = ap->link.device; + + if ((dev->class == ATA_DEV_ATAPI) && + (dev->flags & ATA_DFLAG_AN)) + ata_scsi_media_change_notify(dev); + return 0; + } else { + /* PMP is attached but SNTF is not available. + * ATAPI async media change notification is + * not used. The PMP must be reporting PHY + * status change, schedule EH. + */ + ata_port_schedule_eh(ap); + return 1; + } + } else { + /* PMP is attached and SNTF is available */ + struct ata_link *link; + + /* check and notify ATAPI AN */ + ata_for_each_link(link, ap, EDGE) { + if (!(sntf & (1 << link->pmp))) + continue; + + if ((link->device->class == ATA_DEV_ATAPI) && + (link->device->flags & ATA_DFLAG_AN)) + ata_scsi_media_change_notify(link->device); + } + + /* If PMP is reporting that PHY status of some + * downstream ports has changed, schedule EH. + */ + if (sntf & (1 << SATA_PMP_CTRL_PORT)) { + ata_port_schedule_eh(ap); + return 1; + } + + return 0; + } +} +EXPORT_SYMBOL_GPL(sata_async_notification); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 04275f4c8d36..201165955b90 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1092,80 +1092,6 @@ int ata_port_freeze(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_port_freeze); -/** - * sata_async_notification - SATA async notification handler - * @ap: ATA port where async notification is received - * - * Handler to be called when async notification via SDB FIS is - * received. This function schedules EH if necessary. - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * 1 if EH is scheduled, 0 otherwise. - */ -int sata_async_notification(struct ata_port *ap) -{ - u32 sntf; - int rc; - - if (!(ap->flags & ATA_FLAG_AN)) - return 0; - - rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf); - if (rc == 0) - sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); - - if (!sata_pmp_attached(ap) || rc) { - /* PMP is not attached or SNTF is not available */ - if (!sata_pmp_attached(ap)) { - /* PMP is not attached. Check whether ATAPI - * AN is configured. If so, notify media - * change. - */ - struct ata_device *dev = ap->link.device; - - if ((dev->class == ATA_DEV_ATAPI) && - (dev->flags & ATA_DFLAG_AN)) - ata_scsi_media_change_notify(dev); - return 0; - } else { - /* PMP is attached but SNTF is not available. - * ATAPI async media change notification is - * not used. The PMP must be reporting PHY - * status change, schedule EH. - */ - ata_port_schedule_eh(ap); - return 1; - } - } else { - /* PMP is attached and SNTF is available */ - struct ata_link *link; - - /* check and notify ATAPI AN */ - ata_for_each_link(link, ap, EDGE) { - if (!(sntf & (1 << link->pmp))) - continue; - - if ((link->device->class == ATA_DEV_ATAPI) && - (link->device->flags & ATA_DFLAG_AN)) - ata_scsi_media_change_notify(link->device); - } - - /* If PMP is reporting that PHY status of some - * downstream ports has changed, schedule EH. - */ - if (sntf & (1 << SATA_PMP_CTRL_PORT)) { - ata_port_schedule_eh(ap); - return 1; - } - - return 0; - } -} -EXPORT_SYMBOL_GPL(sata_async_notification); - /** * ata_eh_freeze_port - EH helper to freeze port * @ap: ATA port to freeze diff --git a/include/linux/libata.h b/include/linux/libata.h index eb2797c27547..d09997e2290b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1335,7 +1335,6 @@ extern void ata_port_wait_eh(struct ata_port *ap); extern int ata_link_abort(struct ata_link *link); extern int ata_port_abort(struct ata_port *ap); extern int ata_port_freeze(struct ata_port *ap); -extern int sata_async_notification(struct ata_port *ap); extern void ata_eh_freeze_port(struct ata_port *ap); extern void ata_eh_thaw_port(struct ata_port *ap); @@ -1352,6 +1351,13 @@ extern void ata_std_sched_eh(struct ata_port *ap); extern void ata_std_end_eh(struct ata_port *ap); extern int ata_link_nr_enabled(struct ata_link *link); +/* + * SATA specific part of EH - drivers/ata/libata-eh-sata.c + */ +#ifdef CONFIG_SATA_HOST +extern int sata_async_notification(struct ata_port *ap); +#endif + /* * Base operations to inherit from and initializers for sht * -- 2.24.1