* [PATCH 00/28] ata: optimize core code size on PATA only setups [not found] <CGME20200128133410eucas1p19fb97c9696596da07181e0c630fb6c6b@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133410eucas1p271284329b9b63c2c48167308809c569c@eucas1p2.samsung.com> ` (28 more replies) 0 siblings, 29 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Hi, There have been reports in the past of libata core code size being a problem in migration from deprecated IDE subsystem on legacy PATA only systems, i.e.: https://lore.kernel.org/linux-ide/db2838b7-4862-785b-3a1d-3bf09811340a@gmail.com/ This patchset re-organizes libata core code to exclude SATA specific code from being built for PATA only setups. The end result is up to 17% (by 17246 bytes, from 101787 bytes to 84541 bytes) smaller libata core code size (as measured for m68k arch using atari_defconfig) on affected setups. I've tested this patchset using pata_falcon driver under ARAnyM emulator. patches #1-9 are general fixes/cleanups done in the process of making the patchset (there should be no inter-dependencies between them except patch #9 which depends on patch #8) patch #10 separates PATA timings code to libata-pata-timings.c file patch #11 optimizes ata_ncq_enable() inline for PATA only setups patches #12-22 separate SATA only code from libata-core.c file to libata-core-sata.c one patches #24-25 separate SATA only code from libata-scsi.c file to libata-scsi-sata.c one patches #26-28 separate SATA only code from libata-eh.c file to libata-eh-sata.c one Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics Bartlomiej Zolnierkiewicz (28): ata: remove stale maintainership information from core code ata: expose ncq_enable_prio sysfs attribute only on NCQ capable hosts ata: make SATA_PMP option selectable only if any SATA host driver is enabled sata_promise: use ata_cable_sata() ata: simplify ata_scsiop_inq_89() ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size ata: optimize struct ata_force_param size ata: move EXPORT_SYMBOL_GPL()s close to exported code ata: remove EXPORT_SYMBOL_GPL()s not used by modules ata: separate PATA timings code from libata-core.c ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() ata: start separating SATA specific code from libata-core.c ata: move ata_do_link_spd_horkage() to libata-core-sata.c ata: move ata_dev_config_ncq*() to libata-core-sata.c ata: move sata_print_link_status() to libata-core-sata.c ata: move sata_down_spd_limit() to libata-core-sata.c ata: move *sata_set_spd*() to libata-core-sata.c ata: move sata_link_{debounce,resume}() to libata-core-sata.c ata: move sata_link_hardreset() to libata-core-sata.c ata: move sata_link_init_spd() to libata-core-sata.c ata: move ata_qc_complete_multiple() to libata-core-sata.c ata: move sata_scr_*() to libata-core-sata.c ata: move sata_deb_timing_*() to libata-core-sata.c ata: start separating SATA specific code from libata-scsi.c ata: move ata_sas_*() to libata-scsi-sata.c ata: start separating SATA specific code from libata-eh.c ata: move ata_eh_analyze_ncq_error() & co. to libata-core-sata.c ata: move ata_eh_set_lpm() to libata-core-sata.c drivers/ata/Kconfig | 61 ++ drivers/ata/Makefile | 3 + drivers/ata/libata-core-sata.c | 1077 +++++++++++++++++++++ drivers/ata/libata-core.c | 1456 ++--------------------------- drivers/ata/libata-eh-sata.c | 349 +++++++ drivers/ata/libata-eh.c | 354 +------ drivers/ata/libata-pata-timings.c | 180 ++++ drivers/ata/libata-scsi-sata.c | 523 +++++++++++ drivers/ata/libata-scsi.c | 542 +---------- drivers/ata/libata-sff.c | 4 - drivers/ata/libata.h | 69 +- drivers/ata/sata_promise.c | 8 +- drivers/scsi/Kconfig | 1 + drivers/scsi/libsas/Kconfig | 1 + include/linux/libata.h | 176 ++-- 15 files changed, 2496 insertions(+), 2308 deletions(-) create mode 100644 drivers/ata/libata-core-sata.c create mode 100644 drivers/ata/libata-eh-sata.c create mode 100644 drivers/ata/libata-pata-timings.c create mode 100644 drivers/ata/libata-scsi-sata.c -- 2.24.1 ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133410eucas1p271284329b9b63c2c48167308809c569c@eucas1p2.samsung.com>]
* [PATCH 01/28] ata: remove stale maintainership information from core code [not found] ` <CGME20200128133410eucas1p271284329b9b63c2c48167308809c569c@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-28 14:28 ` Tejun Heo 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie, Tejun Heo In commit 7634ccd2da97 ("libata: maintainership update") from 2018 Jens has officially taken over libata maintainership from Tejun so remove stale information from core libata code. Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- I've not touched host drivers which also list Tejun as Maintainer: drivers/ata/acard-ahci.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/ahci.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/ahci.h: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/ata_piix.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/libahci.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/pdc_adma.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/sata_promise.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/sata_sil.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/sata_sx4.c: * Maintained by: Tejun Heo <tj@kernel.org> drivers/ata/sata_via.c: * Maintained by: Tejun Heo <tj@kernel.org> Tejun, please let me know if you want me to update any of them. drivers/ata/libata-core.c | 4 ---- drivers/ata/libata-eh.c | 4 ---- drivers/ata/libata-scsi.c | 4 ---- drivers/ata/libata-sff.c | 4 ---- 4 files changed, 16 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6f4ab5c5b52d..fa36e3248039 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2,10 +2,6 @@ /* * libata-core.c - helper library for ATA * - * Maintained by: Tejun Heo <tj@kernel.org> - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik * diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 3bfd9da58473..53605c8949d8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2,10 +2,6 @@ /* * libata-eh.c - libata error handling * - * Maintained by: Tejun Heo <tj@kernel.org> - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2006 Tejun Heo <htejun@gmail.com> * * libata documentation is available via 'make {ps|pdf}docs', diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index eb2eb599e602..11eb25b6e2cd 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2,10 +2,6 @@ /* * libata-scsi.c - helper library for ATA * - * Maintained by: Tejun Heo <tj@kernel.org> - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik * diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 038db94216a9..ae7189d1a568 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2,10 +2,6 @@ /* * libata-sff.c - helper library for PCI IDE BMDMA * - * Maintained by: Tejun Heo <tj@kernel.org> - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2006 Red Hat, Inc. All rights reserved. * Copyright 2003-2006 Jeff Garzik * -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 01/28] ata: remove stale maintainership information from core code 2020-01-28 13:33 ` [PATCH 01/28] ata: remove stale maintainership information from core code Bartlomiej Zolnierkiewicz @ 2020-01-28 14:28 ` Tejun Heo 0 siblings, 0 replies; 54+ messages in thread From: Tejun Heo @ 2020-01-28 14:28 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:16PM +0100, Bartlomiej Zolnierkiewicz wrote: > In commit 7634ccd2da97 ("libata: maintainership update") from 2018 > Jens has officially taken over libata maintainership from Tejun so > remove stale information from core libata code. > > Cc: Tejun Heo <tj@kernel.org> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133411eucas1p2db496c50fea321b621b1a07b4b8a8cc2@eucas1p2.samsung.com>]
* [PATCH 02/28] ata: expose ncq_enable_prio sysfs attribute only on NCQ capable hosts [not found] ` <CGME20200128133411eucas1p2db496c50fea321b621b1a07b4b8a8cc2@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie There is no point in exposing ncq_enable_prio sysfs attribute for devices on PATA and non-NCQ capable SATA hosts so: * remove dev_attr_ncq_prio_enable from ata_common_sdev_attrs[] * add ata_ncq_sdev_attrs[] * update ATA_NCQ_SHT() macro to use ata_ncq_sdev_attrs[] Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-scsi.c | 8 +++++++- include/linux/libata.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 11eb25b6e2cd..161e5d84bd82 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -462,11 +462,17 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity); struct device_attribute *ata_common_sdev_attrs[] = { &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, NULL }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); +struct device_attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads, + &dev_attr_ncq_prio_enable, + NULL +}; +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); + /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined diff --git a/include/linux/libata.h b/include/linux/libata.h index a36bdcb8d9e9..2a9d50b0e219 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1335,6 +1335,7 @@ extern int ata_link_nr_enabled(struct ata_link *link); extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; extern struct device_attribute *ata_common_sdev_attrs[]; +extern struct device_attribute *ata_ncq_sdev_attrs[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1361,6 +1362,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; #define ATA_NCQ_SHT(drv_name) \ ATA_BASE_SHT(drv_name), \ + .sdev_attrs = ata_ncq_sdev_attrs, \ .change_queue_depth = ata_scsi_change_queue_depth /* -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133411eucas1p1671c280eb6f5d2ca2d10743eea6c96e5@eucas1p1.samsung.com>]
* [PATCH 03/28] ata: make SATA_PMP option selectable only if any SATA host driver is enabled [not found] ` <CGME20200128133411eucas1p1671c280eb6f5d2ca2d10743eea6c96e5@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 2:35 ` Martin K. Petersen 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie, James E.J. Bottomley, Martin K. Petersen There is no reason to expose SATA_PMP config option when no SATA host drivers are enabled. To fix it add SATA_HOST config option, make all SATA host drivers select it and finally make SATA_PMP config options depend on it. This also serves as a preparation for the future changes which optimize libata core code size on PATA only setups. Cc: "James E.J. Bottomley" <jejb@linux.ibm.com> Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/Kconfig | 40 +++++++++++++++++++++++++++++++++++++ drivers/scsi/Kconfig | 1 + drivers/scsi/libsas/Kconfig | 1 + 3 files changed, 42 insertions(+) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a6beb2c5a692..ad7760656f71 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -34,6 +34,9 @@ if ATA config ATA_NONSTANDARD bool +config SATA_HOST + bool + config ATA_VERBOSE_ERROR bool "Verbose ATA error reporting" default y @@ -73,6 +76,7 @@ config SATA_ZPODD config SATA_PMP bool "SATA Port Multiplier support" + depends on SATA_HOST default y help This option adds support for SATA Port Multipliers @@ -85,6 +89,7 @@ comment "Controllers with non-SFF native interface" config SATA_AHCI tristate "AHCI SATA support" depends on PCI + select SATA_HOST help This option enables support for AHCI Serial ATA. @@ -111,6 +116,7 @@ config SATA_MOBILE_LPM_POLICY config SATA_AHCI_PLATFORM tristate "Platform AHCI SATA support" + select SATA_HOST help This option enables support for Platform AHCI Serial ATA controllers. @@ -121,6 +127,7 @@ config AHCI_BRCM tristate "Broadcom AHCI SATA support" depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \ ARCH_BCM_63XX + select SATA_HOST help This option enables support for the AHCI SATA3 controller found on Broadcom SoC's. @@ -130,6 +137,7 @@ config AHCI_BRCM config AHCI_DA850 tristate "DaVinci DA850 AHCI SATA support" depends on ARCH_DAVINCI_DA850 + select SATA_HOST help This option enables support for the DaVinci DA850 SoC's onboard AHCI SATA. @@ -139,6 +147,7 @@ config AHCI_DA850 config AHCI_DM816 tristate "DaVinci DM816 AHCI SATA support" depends on ARCH_OMAP2PLUS + select SATA_HOST help This option enables support for the DaVinci DM816 SoC's onboard AHCI SATA controller. @@ -148,6 +157,7 @@ config AHCI_DM816 config AHCI_ST tristate "ST AHCI SATA support" depends on ARCH_STI + select SATA_HOST help This option enables support for ST AHCI SATA controller. @@ -157,6 +167,7 @@ config AHCI_IMX tristate "Freescale i.MX AHCI SATA support" depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON + select SATA_HOST help This option enables support for the Freescale i.MX SoC's onboard AHCI SATA. @@ -166,6 +177,7 @@ config AHCI_IMX config AHCI_CEVA tristate "CEVA AHCI SATA support" depends on OF + select SATA_HOST help This option enables support for the CEVA AHCI SATA. It can be found on the Xilinx Zynq UltraScale+ MPSoC. @@ -176,6 +188,7 @@ config AHCI_MTK tristate "MediaTek AHCI SATA support" depends on ARCH_MEDIATEK select MFD_SYSCON + select SATA_HOST help This option enables support for the MediaTek SoC's onboard AHCI SATA controller. @@ -185,6 +198,7 @@ config AHCI_MTK config AHCI_MVEBU tristate "Marvell EBU AHCI SATA support" depends on ARCH_MVEBU + select SATA_HOST help This option enables support for the Marvebu EBU SoC's onboard AHCI SATA. @@ -203,6 +217,7 @@ config AHCI_OCTEON config AHCI_SUNXI tristate "Allwinner sunxi AHCI SATA support" depends on ARCH_SUNXI + select SATA_HOST help This option enables support for the Allwinner sunxi SoC's onboard AHCI SATA. @@ -212,6 +227,7 @@ config AHCI_SUNXI config AHCI_TEGRA tristate "NVIDIA Tegra AHCI SATA support" depends on ARCH_TEGRA + select SATA_HOST help This option enables support for the NVIDIA Tegra SoC's onboard AHCI SATA. @@ -221,12 +237,14 @@ config AHCI_TEGRA config AHCI_XGENE tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" depends on PHY_XGENE + select SATA_HOST help This option enables support for APM X-Gene SoC SATA host controller. config AHCI_QORIQ tristate "Freescale QorIQ AHCI SATA support" depends on OF + select SATA_HOST help This option enables support for the Freescale QorIQ AHCI SoC's onboard AHCI SATA. @@ -236,6 +254,7 @@ config AHCI_QORIQ config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC + select SATA_HOST help This option enables support for Freescale 3.0Gbps SATA controller. It can be found on MPC837x and MPC8315. @@ -245,6 +264,7 @@ config SATA_FSL config SATA_GEMINI tristate "Gemini SATA bridge support" depends on ARCH_GEMINI || COMPILE_TEST + select SATA_HOST default ARCH_GEMINI help This enabled support for the FTIDE010 to SATA bridge @@ -255,6 +275,7 @@ config SATA_GEMINI config SATA_AHCI_SEATTLE tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" depends on ARCH_SEATTLE + select SATA_HOST help This option enables support for AMD Seattle SATA host controller. @@ -263,12 +284,14 @@ config SATA_AHCI_SEATTLE config SATA_INIC162X tristate "Initio 162x SATA support (Very Experimental)" depends on PCI + select SATA_HOST help This option enables support for Initio 162x Serial ATA. config SATA_ACARD_AHCI tristate "ACard AHCI variant (ATP 8620)" depends on PCI + select SATA_HOST help This option enables support for Acard. @@ -277,6 +300,7 @@ config SATA_ACARD_AHCI config SATA_SIL24 tristate "Silicon Image 3124/3132 SATA support" depends on PCI + select SATA_HOST help This option enables support for Silicon Image 3124/3132 Serial ATA. @@ -326,6 +350,7 @@ config PATA_OCTEON_CF config SATA_QSTOR tristate "Pacific Digital SATA QStor support" depends on PCI + select SATA_HOST help This option enables support for Pacific Digital Serial ATA QStor. @@ -334,6 +359,7 @@ config SATA_QSTOR config SATA_SX4 tristate "Promise SATA SX4 support (Experimental)" depends on PCI + select SATA_HOST help This option enables support for Promise Serial ATA SX4. @@ -357,6 +383,7 @@ comment "SATA SFF controllers with BMDMA" config ATA_PIIX tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" depends on PCI + select SATA_HOST help This option enables support for ICH5/6/7/8 Serial ATA and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series @@ -368,6 +395,7 @@ config SATA_DWC tristate "DesignWare Cores SATA support" depends on DMADEVICES select GENERIC_PHY + select SATA_HOST help This option enables support for the on-chip SATA controller of the AppliedMicro processor 460EX. @@ -398,6 +426,7 @@ config SATA_DWC_VDEBUG config SATA_HIGHBANK tristate "Calxeda Highbank SATA support" depends on ARCH_HIGHBANK || COMPILE_TEST + select SATA_HOST help This option enables support for the Calxeda Highbank SoC's onboard SATA. @@ -409,6 +438,7 @@ config SATA_MV depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \ ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST select GENERIC_PHY + select SATA_HOST help This option enables support for the Marvell Serial ATA family. Currently supports 88SX[56]0[48][01] PCI(-X) chips, @@ -419,6 +449,7 @@ config SATA_MV config SATA_NV tristate "NVIDIA SATA support" depends on PCI + select SATA_HOST help This option enables support for NVIDIA Serial ATA. @@ -427,6 +458,7 @@ config SATA_NV config SATA_PROMISE tristate "Promise SATA TX2/TX4 support" depends on PCI + select SATA_HOST help This option enables support for Promise Serial ATA TX2/TX4. @@ -435,6 +467,7 @@ config SATA_PROMISE config SATA_RCAR tristate "Renesas R-Car SATA support" depends on ARCH_RENESAS || COMPILE_TEST + select SATA_HOST help This option enables support for Renesas R-Car Serial ATA. @@ -443,6 +476,7 @@ config SATA_RCAR config SATA_SIL tristate "Silicon Image SATA support" depends on PCI + select SATA_HOST help This option enables support for Silicon Image Serial ATA. @@ -452,6 +486,7 @@ config SATA_SIS tristate "SiS 964/965/966/180 SATA support" depends on PCI select PATA_SIS + select SATA_HOST help This option enables support for SiS Serial ATA on SiS 964/965/966/180 and Parallel ATA on SiS 180. @@ -462,6 +497,7 @@ config SATA_SIS config SATA_SVW tristate "ServerWorks Frodo / Apple K2 SATA support" depends on PCI + select SATA_HOST help This option enables support for Broadcom/Serverworks/Apple K2 SATA support. @@ -471,6 +507,7 @@ config SATA_SVW config SATA_ULI tristate "ULi Electronics SATA support" depends on PCI + select SATA_HOST help This option enables support for ULi Electronics SATA. @@ -479,6 +516,7 @@ config SATA_ULI config SATA_VIA tristate "VIA SATA support" depends on PCI + select SATA_HOST help This option enables support for VIA Serial ATA. @@ -487,6 +525,7 @@ config SATA_VIA config SATA_VITESSE tristate "VITESSE VSC-7174 / INTEL 31244 SATA support" depends on PCI + select SATA_HOST help This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA. @@ -1113,6 +1152,7 @@ config PATA_ACPI config ATA_GENERIC tristate "Generic ATA support" depends on PCI && ATA_BMDMA + select SATA_HOST help This option enables support for generic BIOS configured ATA controllers via the new ATA layer diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a7881f8eb05e..1b6eaf8da5fa 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO config SCSI_IPR tristate "IBM Power Linux RAID adapter support" depends on PCI && SCSI && ATA + select SATA_HOST select FW_LOADER select IRQ_POLL select SGL_ALLOC diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig index 5c6a5eff2f8e..052ee3a26f6e 100644 --- a/drivers/scsi/libsas/Kconfig +++ b/drivers/scsi/libsas/Kconfig @@ -19,6 +19,7 @@ config SCSI_SAS_ATA bool "ATA support for libsas (requires libata)" depends on SCSI_SAS_LIBSAS depends on ATA = y || ATA = SCSI_SAS_LIBSAS + select SATA_HOST help Builds in ATA support into libsas. Will necessitate the loading of libata along with libsas. -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 03/28] ata: make SATA_PMP option selectable only if any SATA host driver is enabled 2020-01-28 13:33 ` [PATCH 03/28] ata: make SATA_PMP option selectable only if any SATA host driver is enabled Bartlomiej Zolnierkiewicz @ 2020-01-29 2:35 ` Martin K. Petersen 0 siblings, 0 replies; 54+ messages in thread From: Martin K. Petersen @ 2020-01-29 2:35 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, James E.J. Bottomley, Martin K. Petersen Bartlomiej, > diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig > index a7881f8eb05e..1b6eaf8da5fa 100644 > --- a/drivers/scsi/Kconfig > +++ b/drivers/scsi/Kconfig > @@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO > config SCSI_IPR > tristate "IBM Power Linux RAID adapter support" > depends on PCI && SCSI && ATA > + select SATA_HOST > select FW_LOADER > select IRQ_POLL > select SGL_ALLOC > diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig > index 5c6a5eff2f8e..052ee3a26f6e 100644 > --- a/drivers/scsi/libsas/Kconfig > +++ b/drivers/scsi/libsas/Kconfig > @@ -19,6 +19,7 @@ config SCSI_SAS_ATA > bool "ATA support for libsas (requires libata)" > depends on SCSI_SAS_LIBSAS > depends on ATA = y || ATA = SCSI_SAS_LIBSAS > + select SATA_HOST > help > Builds in ATA support into libsas. Will necessitate > the loading of libata along with libsas. SCSI bits look fine. Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> -- Martin K. Petersen Oracle Linux Engineering ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133412eucas1p2c79626824fcadc63c133548cd2e7d8cf@eucas1p2.samsung.com>]
* [PATCH 04/28] sata_promise: use ata_cable_sata() [not found] ` <CGME20200128133412eucas1p2c79626824fcadc63c133548cd2e7d8cf@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie, Mikael Pettersson Use core helper instead of open-coding it. Cc: Mikael Pettersson <mikpelinux@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/sata_promise.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index c451d7d1c817..8729f78cef5f 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, static void pdc_error_handler(struct ata_port *ap); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static int pdc_pata_cable_detect(struct ata_port *ap); -static int pdc_sata_cable_detect(struct ata_port *ap); static struct scsi_host_template pdc_ata_sht = { ATA_BASE_SHT(DRV_NAME), @@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = { static struct ata_port_operations pdc_sata_ops = { .inherits = &pdc_common_ops, - .cable_detect = pdc_sata_cable_detect, + .cable_detect = ata_cable_sata, .freeze = pdc_sata_freeze, .thaw = pdc_sata_thaw, .scr_read = pdc_sata_scr_read, @@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } -static int pdc_sata_cable_detect(struct ata_port *ap) -{ - return ATA_CBL_SATA; -} - static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) { -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133412eucas1p258499338146481964e4c26ad3f1cbf14@eucas1p2.samsung.com>]
* [PATCH 05/28] ata: simplify ata_scsiop_inq_89() [not found] ` <CGME20200128133412eucas1p258499338146481964e4c26ad3f1cbf14@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:15 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Initialize rbuf[] directly instead of using ata_tf_to_fis(). This results in simpler and smaller code. It also allows separating ata_tf_to_fis() into SATA specific libata part in the future. Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 20824 105 4096 25025 61c1 drivers/ata/libata-scsi.o after: 20782 105 4096 24983 6197 drivers/ata/libata-scsi.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-scsi.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 161e5d84bd82..cc8ba49275e7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2356,10 +2356,6 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf) */ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) { - struct ata_taskfile tf; - - memset(&tf, 0, sizeof(tf)); - rbuf[1] = 0x89; /* our page code */ rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */ rbuf[3] = (0x238 & 0xff); @@ -2368,14 +2364,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) memcpy(&rbuf[16], "libata ", 16); memcpy(&rbuf[32], DRV_VERSION, 4); - /* we don't store the ATA device signature, so we fake it */ - - tf.command = ATA_DRDY; /* really, this is Status reg */ - tf.lbal = 0x1; - tf.nsect = 0x1; - - ata_tf_to_fis(&tf, 0, 1, &rbuf[36]); /* TODO: PMP? */ rbuf[36] = 0x34; /* force D2H Reg FIS (34h) */ + rbuf[37] = (1 << 7); /* bit 7 indicates Command FIS */ + /* TODO: PMP? */ + + /* we don't store the ATA device signature, so we fake it */ + rbuf[38] = ATA_DRDY; /* really, this is Status reg */ + rbuf[40] = 0x1; + rbuf[48] = 0x1; rbuf[56] = ATA_CMD_ID_ATA; -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 05/28] ata: simplify ata_scsiop_inq_89() 2020-01-28 13:33 ` [PATCH 05/28] ata: simplify ata_scsiop_inq_89() Bartlomiej Zolnierkiewicz @ 2020-01-29 17:15 ` Christoph Hellwig 0 siblings, 0 replies; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:15 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133412eucas1p2e5e3e29ea554bf57c1f2cc05b3d2d3a8@eucas1p2.samsung.com>]
* [PATCH 06/28] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size [not found] ` <CGME20200128133412eucas1p2e5e3e29ea554bf57c1f2cc05b3d2d3a8@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Use COMMAND_LINE_SIZE instead PAGE_SIZE for ata_force_param_buf[] size as libata parameters buffer doesn't need to be bigger than the command line buffer. For many architectures this results in decreased libata-core.o size (COMMAND_LINE_SIZE varies from 256 to 4096 while the minimum PAGE_SIZE is 4096). Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 41064 4413 40 45517 b1cd drivers/ata/libata-core.o after: 41064 573 40 41677 a2cd drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fa36e3248039..9b824788d04f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -52,6 +52,7 @@ #include <linux/leds.h> #include <linux/pm_runtime.h> #include <linux/platform_device.h> +#include <asm/setup.h> #define CREATE_TRACE_POINTS #include <trace/events/libata.h> @@ -106,7 +107,7 @@ struct ata_force_ent { static struct ata_force_ent *ata_force_tbl; static int ata_force_tbl_size; -static char ata_force_param_buf[PAGE_SIZE] __initdata; +static char ata_force_param_buf[COMMAND_LINE_SIZE] __initdata; /* param_buf is thrown away after initialization, disallow read */ module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/admin-guide/kernel-parameters.rst for details)"); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 06/28] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size 2020-01-28 13:33 ` [PATCH 06/28] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size Bartlomiej Zolnierkiewicz @ 2020-01-29 17:18 ` Christoph Hellwig 2020-02-07 14:17 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:18 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:21PM +0100, Bartlomiej Zolnierkiewicz wrote: > Use COMMAND_LINE_SIZE instead PAGE_SIZE for ata_force_param_buf[] > size as libata parameters buffer doesn't need to be bigger than > the command line buffer. > > For many architectures this results in decreased libata-core.o > size (COMMAND_LINE_SIZE varies from 256 to 4096 while the minimum > PAGE_SIZE is 4096). > > Code size savings on m68k arch using atari_defconfig: > > text data bss dec hex filename > before: > 41064 4413 40 45517 b1cd drivers/ata/libata-core.o > after: > 41064 573 40 41677 a2cd drivers/ata/libata-core.o > > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> This looks like a good start, so: Reviewed-by: Christoph Hellwig <hch@lst.de> But evne COMMAND_LINE_SIZE is quite a lot of overhead. Can we maybe add a new Kconfig option to optionally disable the libata.force= entirely? ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 06/28] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size 2020-01-29 17:18 ` Christoph Hellwig @ 2020-02-07 14:17 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:17 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:18 PM, Christoph Hellwig wrote: > On Tue, Jan 28, 2020 at 02:33:21PM +0100, Bartlomiej Zolnierkiewicz wrote: >> Use COMMAND_LINE_SIZE instead PAGE_SIZE for ata_force_param_buf[] >> size as libata parameters buffer doesn't need to be bigger than >> the command line buffer. >> >> For many architectures this results in decreased libata-core.o >> size (COMMAND_LINE_SIZE varies from 256 to 4096 while the minimum >> PAGE_SIZE is 4096). >> >> Code size savings on m68k arch using atari_defconfig: >> >> text data bss dec hex filename >> before: >> 41064 4413 40 45517 b1cd drivers/ata/libata-core.o >> after: >> 41064 573 40 41677 a2cd drivers/ata/libata-core.o >> >> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > > This looks like a good start, so: > > Reviewed-by: Christoph Hellwig <hch@lst.de> Thanks. > But evne COMMAND_LINE_SIZE is quite a lot of overhead. Can we maybe add > a new Kconfig option to optionally disable the libata.force= entirely? I've added patch making "libata.force=" optional in v2 (disabling "libata.force=" saves us additional 3kB). Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133412eucas1p1b1b4f025e4c0e6ae6e7a95e9832880dd@eucas1p1.samsung.com>]
* [PATCH 07/28] ata: optimize struct ata_force_param size [not found] ` <CGME20200128133412eucas1p1b1b4f025e4c0e6ae6e7a95e9832880dd@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Optimize struct ata_force_param size by: - using u8 for cbl and spd_limit fields - using u16 for lflags field Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 41064 573 40 41677 a2cd drivers/ata/libata-core.o after: 40654 573 40 41267 a133 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core.c | 6 +++--- include/linux/libata.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9b824788d04f..47703c8ba0e6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -90,12 +90,12 @@ atomic_t ata_print_id = ATOMIC_INIT(0); struct ata_force_param { const char *name; - unsigned int cbl; - int spd_limit; + u8 cbl; + u8 spd_limit; unsigned long xfer_mask; unsigned int horkage_on; unsigned int horkage_off; - unsigned int lflags; + u16 lflags; }; struct ata_force_ent { diff --git a/include/linux/libata.h b/include/linux/libata.h index 2a9d50b0e219..dc162cca63a4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -176,6 +176,7 @@ enum { ATA_DEV_NONE = 11, /* no device */ /* struct ata_link flags */ + /* NOTE: struct ata_force_param currently stores lflags in u16 */ ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */ ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */ ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 07/28] ata: optimize struct ata_force_param size 2020-01-28 13:33 ` [PATCH 07/28] ata: optimize struct ata_force_param size Bartlomiej Zolnierkiewicz @ 2020-01-29 17:18 ` Christoph Hellwig 0 siblings, 0 replies; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:18 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133413eucas1p195d291f69413cbb3bb86da9571942259@eucas1p1.samsung.com>]
* [PATCH 08/28] ata: move EXPORT_SYMBOL_GPL()s close to exported code [not found] ` <CGME20200128133413eucas1p195d291f69413cbb3bb86da9571942259@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Move EXPORT_SYMBOL_GPL()s close to exported code like it is done in other kernel subsystems. As a nice side effect this results in the removal of few ifdefs. Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core.c | 206 +++++++++++++++----------------------- drivers/ata/libata-eh.c | 20 +++- drivers/ata/libata-scsi.c | 8 ++ 3 files changed, 108 insertions(+), 126 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 47703c8ba0e6..ad724602c47c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -18,6 +18,11 @@ * http://www.compactflash.org (CF) * http://www.qic.org (QIC157 - Tape and DSC) * http://www.ce-ata.org (CE-ATA: not supported) + * + * libata is essentially a library of internal helper functions for + * low-level ATA host controller drivers. As such, the API/ABI is + * likely to change as new drivers are added and updated. + * Do not depend on ABI/API stability. */ #include <linux/kernel.h> @@ -62,8 +67,11 @@ /* debounce timing parameters in msecs { interval, duration, timeout } */ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_normal); const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_long); const struct ata_port_operations ata_base_port_ops = { .prereset = ata_std_prereset, @@ -72,6 +80,7 @@ const struct ata_port_operations ata_base_port_ops = { .sched_eh = ata_std_sched_eh, .end_eh = ata_std_end_eh, }; +EXPORT_SYMBOL_GPL(ata_base_port_ops); const struct ata_port_operations sata_port_ops = { .inherits = &ata_base_port_ops, @@ -79,6 +88,7 @@ const struct ata_port_operations sata_port_ops = { .qc_defer = ata_std_qc_defer, .hardreset = sata_std_hardreset, }; +EXPORT_SYMBOL_GPL(sata_port_ops); static unsigned int ata_dev_init_params(struct ata_device *dev, u16 heads, u16 sectors); @@ -221,6 +231,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap, return NULL; } +EXPORT_SYMBOL_GPL(ata_link_next); /** * ata_dev_next - device iteration helper @@ -274,6 +285,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link, goto next; return dev; } +EXPORT_SYMBOL_GPL(ata_dev_next); /** * ata_dev_phys_link - find physical link for a device @@ -518,6 +530,7 @@ int atapi_cmd_type(u8 opcode) return ATAPI_MISC; } } +EXPORT_SYMBOL_GPL(atapi_cmd_type); /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure @@ -562,6 +575,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) fis[18] = (tf->auxiliary >> 16) & 0xff; fis[19] = (tf->auxiliary >> 24) & 0xff; } +EXPORT_SYMBOL_GPL(ata_tf_to_fis); /** * ata_tf_from_fis - Convert SATA FIS to ATA taskfile @@ -591,6 +605,7 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) tf->nsect = fis[12]; tf->hob_nsect = fis[13]; } +EXPORT_SYMBOL_GPL(ata_tf_from_fis); static const u8 ata_rw_cmds[] = { /* pio multi */ @@ -865,6 +880,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask, ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); } +EXPORT_SYMBOL_GPL(ata_pack_xfermask); /** * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks @@ -886,6 +902,7 @@ void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask, if (udma_mask) *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; } +EXPORT_SYMBOL_GPL(ata_unpack_xfermask); static const struct ata_xfer_ent { int shift, bits; @@ -920,6 +937,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask) return ent->base + highbit - ent->shift; return 0xff; } +EXPORT_SYMBOL_GPL(ata_xfer_mask2mode); /** * ata_xfer_mode2mask - Find matching xfer_mask for XFER_* @@ -943,6 +961,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode) & ~((1 << ent->shift) - 1); return 0; } +EXPORT_SYMBOL_GPL(ata_xfer_mode2mask); /** * ata_xfer_mode2shift - Find matching xfer_shift for XFER_* @@ -965,6 +984,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode) return ent->shift; return -1; } +EXPORT_SYMBOL_GPL(ata_xfer_mode2shift); /** * ata_mode_string - convert xfer_mask to string @@ -1011,6 +1031,7 @@ const char *ata_mode_string(unsigned long xfer_mask) return xfer_mode_str[highbit]; return "<n/a>"; } +EXPORT_SYMBOL_GPL(ata_mode_string); const char *sata_spd_string(unsigned int spd) { @@ -1091,6 +1112,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) DPRINTK("unknown device\n"); return ATA_DEV_UNKNOWN; } +EXPORT_SYMBOL_GPL(ata_dev_classify); /** * ata_id_string - Convert IDENTIFY DEVICE page into string @@ -1127,6 +1149,7 @@ void ata_id_string(const u16 *id, unsigned char *s, len -= 2; } } +EXPORT_SYMBOL_GPL(ata_id_string); /** * ata_id_c_string - Convert IDENTIFY DEVICE page into C string @@ -1154,6 +1177,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s, p--; *p = '\0'; } +EXPORT_SYMBOL_GPL(ata_id_c_string); static u64 ata_id_n_sectors(const u16 *id) { @@ -1511,6 +1535,7 @@ unsigned long ata_id_xfermask(const u16 *id) return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); } +EXPORT_SYMBOL_GPL(ata_id_xfermask); static void ata_qc_complete_internal(struct ata_queued_cmd *qc) { @@ -1768,6 +1793,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) return 1; return 0; } +EXPORT_SYMBOL_GPL(ata_pio_need_iordy); /** * ata_pio_mask_no_iordy - Return the non IORDY mask @@ -1808,6 +1834,7 @@ unsigned int ata_do_dev_read_id(struct ata_device *dev, return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, sizeof(id[0]) * ATA_ID_WORDS, 0); } +EXPORT_SYMBOL_GPL(ata_do_dev_read_id); /** * ata_dev_read_id - Read ID data from the specified device @@ -2780,6 +2807,7 @@ int ata_cable_40wire(struct ata_port *ap) { return ATA_CBL_PATA40; } +EXPORT_SYMBOL_GPL(ata_cable_40wire); /** * ata_cable_80wire - return 80 wire cable type @@ -2793,6 +2821,7 @@ int ata_cable_80wire(struct ata_port *ap) { return ATA_CBL_PATA80; } +EXPORT_SYMBOL_GPL(ata_cable_80wire); /** * ata_cable_unknown - return unknown PATA cable. @@ -2805,6 +2834,7 @@ int ata_cable_unknown(struct ata_port *ap) { return ATA_CBL_PATA_UNK; } +EXPORT_SYMBOL_GPL(ata_cable_unknown); /** * ata_cable_ignore - return ignored PATA cable. @@ -2817,6 +2847,7 @@ int ata_cable_ignore(struct ata_port *ap) { return ATA_CBL_PATA_IGN; } +EXPORT_SYMBOL_GPL(ata_cable_ignore); /** * ata_cable_sata - return SATA cable type @@ -2829,6 +2860,7 @@ int ata_cable_sata(struct ata_port *ap) { return ATA_CBL_SATA; } +EXPORT_SYMBOL_GPL(ata_cable_sata); /** * ata_bus_probe - Reset and probe ATA bus @@ -3011,6 +3043,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) return NULL; return pair; } +EXPORT_SYMBOL_GPL(ata_dev_pair); /** * sata_down_spd_limit - adjust SATA spd limit downward @@ -3171,6 +3204,7 @@ int sata_set_spd(struct ata_link *link) return 1; } +EXPORT_SYMBOL_GPL(sata_set_spd); /* * This mode timing computation functionality is ported over from @@ -3245,6 +3279,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); } +EXPORT_SYMBOL_GPL(ata_timing_merge); const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) { @@ -3261,6 +3296,7 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) return NULL; } +EXPORT_SYMBOL_GPL(ata_timing_find_mode); int ata_timing_compute(struct ata_device *adev, unsigned short speed, struct ata_timing *t, int T, int UT) @@ -3337,6 +3373,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, return 0; } +EXPORT_SYMBOL_GPL(ata_timing_compute); /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration @@ -3388,6 +3425,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } +EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); /** * ata_down_xfermask_limit - adjust dev xfer masks downward @@ -3659,6 +3697,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) *r_failed_dev = dev; return rc; } +EXPORT_SYMBOL_GPL(ata_do_set_mode); /** * ata_wait_ready - wait for link to become ready @@ -3768,6 +3807,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, return ata_wait_ready(link, deadline, check_ready); } +EXPORT_SYMBOL_GPL(ata_wait_after_reset); /** * sata_link_debounce - debounce SATA phy status @@ -3838,6 +3878,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, return -EPIPE; } } +EXPORT_SYMBOL_GPL(sata_link_debounce); /** * sata_link_resume - resume SATA link @@ -3904,6 +3945,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, return rc != -EINVAL ? rc : 0; } +EXPORT_SYMBOL_GPL(sata_link_resume); /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields @@ -3978,6 +4020,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, ehc->i.serror &= ~SERR_PHYRDY_CHG; return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); } +EXPORT_SYMBOL_GPL(sata_link_scr_lpm); /** * ata_std_prereset - prepare for reset @@ -4023,6 +4066,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) return 0; } +EXPORT_SYMBOL_GPL(ata_std_prereset); /** * sata_link_hardreset - reset link via SATA phy reset @@ -4135,6 +4179,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, DPRINTK("EXIT, rc=%d\n", rc); return rc; } +EXPORT_SYMBOL_GPL(sata_link_hardreset); /** * sata_std_hardreset - COMRESET w/o waiting or classification @@ -4161,6 +4206,7 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, rc = sata_link_hardreset(link, timing, deadline, &online, NULL); return online ? -EAGAIN : rc; } +EXPORT_SYMBOL_GPL(sata_std_hardreset); /** * ata_std_postreset - standard postreset callback @@ -4189,6 +4235,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) DPRINTK("EXIT\n"); } +EXPORT_SYMBOL_GPL(ata_std_postreset); /** * ata_dev_same_device - Determine whether new ID matches configured device @@ -4976,11 +5023,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) return ATA_DEFER_LINK; } +EXPORT_SYMBOL_GPL(ata_std_qc_defer); enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc) { return AC_ERR_OK; } +EXPORT_SYMBOL_GPL(ata_noop_qc_prep); /** * ata_sg_init - Associate command with scatter-gather table. @@ -5002,6 +5051,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->n_elem = n_elem; qc->cursg = qc->sg; } +EXPORT_SYMBOL_GPL(ata_sg_init); #ifdef CONFIG_HAS_DMA @@ -5324,6 +5374,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) __ata_qc_complete(qc); } } +EXPORT_SYMBOL_GPL(ata_qc_complete); /** * ata_qc_get_active - get bitmask of active qcs @@ -5406,6 +5457,7 @@ int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) return nr_done; } +EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); /** * ata_qc_issue - issue taskfile to device @@ -5500,6 +5552,7 @@ int sata_scr_valid(struct ata_link *link) return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read; } +EXPORT_SYMBOL_GPL(sata_scr_valid); /** * sata_scr_read - read SCR register of the specified port @@ -5527,6 +5580,7 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val) return sata_pmp_scr_read(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_read); /** * sata_scr_write - write SCR register of the specified port @@ -5554,6 +5608,7 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val) return sata_pmp_scr_write(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_write); /** * sata_scr_write_flush - write SCR register of the specified port and flush @@ -5586,6 +5641,7 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) return sata_pmp_scr_write(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_write_flush); /** * ata_phys_link_online - test whether the given link is online @@ -5660,6 +5716,7 @@ bool ata_link_online(struct ata_link *link) return ata_phys_link_online(link) || (slave && ata_phys_link_online(slave)); } +EXPORT_SYMBOL_GPL(ata_link_online); /** * ata_link_offline - test whether the given link is offline @@ -5686,6 +5743,7 @@ bool ata_link_offline(struct ata_link *link) return ata_phys_link_offline(link) && (!slave || ata_phys_link_offline(slave)); } +EXPORT_SYMBOL_GPL(ata_link_offline); #ifdef CONFIG_PM static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, @@ -5872,6 +5930,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) host->dev->power.power_state = mesg; return 0; } +EXPORT_SYMBOL_GPL(ata_host_suspend); /** * ata_host_resume - resume host @@ -5883,6 +5942,7 @@ void ata_host_resume(struct ata_host *host) { host->dev->power.power_state = PMSG_ON; } +EXPORT_SYMBOL_GPL(ata_host_resume); #endif const struct device_type ata_port_type = { @@ -6097,11 +6157,13 @@ void ata_host_get(struct ata_host *host) { kref_get(&host->kref); } +EXPORT_SYMBOL_GPL(ata_host_get); void ata_host_put(struct ata_host *host) { kref_put(&host->kref, ata_host_release); } +EXPORT_SYMBOL_GPL(ata_host_put); /** * ata_host_alloc - allocate and init basic ATA host resources @@ -6175,6 +6237,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) kfree(host); return NULL; } +EXPORT_SYMBOL_GPL(ata_host_alloc); /** * ata_host_alloc_pinfo - alloc host and init with port_info array @@ -6223,6 +6286,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, return host; } +EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); /** * ata_slave_link_init - initialize slave link @@ -6285,6 +6349,7 @@ int ata_slave_link_init(struct ata_port *ap) ap->slave_link = link; return 0; } +EXPORT_SYMBOL_GPL(ata_slave_link_init); static void ata_host_stop(struct device *gendev, void *res) { @@ -6433,6 +6498,7 @@ int ata_host_start(struct ata_host *host) devres_free(start_dr); return rc; } +EXPORT_SYMBOL_GPL(ata_host_start); /** * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas) @@ -6451,6 +6517,7 @@ void ata_host_init(struct ata_host *host, struct device *dev, host->ops = ops; kref_init(&host->kref); } +EXPORT_SYMBOL_GPL(ata_host_init); void __ata_port_probe(struct ata_port *ap) { @@ -6606,6 +6673,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) return rc; } +EXPORT_SYMBOL_GPL(ata_host_register); /** * ata_host_activate - start host, request IRQ and register it @@ -6668,6 +6736,7 @@ int ata_host_activate(struct ata_host *host, int irq, return rc; } +EXPORT_SYMBOL_GPL(ata_host_activate); /** * ata_port_detach - Detach ATA port in preparation of device removal @@ -6743,6 +6812,7 @@ void ata_host_detach(struct ata_host *host) /* the host is dead now, dissociate ACPI */ ata_acpi_dissociate(host); } +EXPORT_SYMBOL_GPL(ata_host_detach); #ifdef CONFIG_PCI @@ -6763,6 +6833,7 @@ void ata_pci_remove_one(struct pci_dev *pdev) ata_host_detach(host); } +EXPORT_SYMBOL_GPL(ata_pci_remove_one); /* move to PCI subsystem */ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) @@ -6797,6 +6868,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) return (tmp == bits->val) ? 1 : 0; } +EXPORT_SYMBOL_GPL(pci_test_config_bits); #ifdef CONFIG_PM void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) @@ -6807,6 +6879,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); } +EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend); int ata_pci_device_do_resume(struct pci_dev *pdev) { @@ -6825,6 +6898,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev) pci_set_master(pdev); return 0; } +EXPORT_SYMBOL_GPL(ata_pci_device_do_resume); int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { @@ -6839,6 +6913,7 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) return 0; } +EXPORT_SYMBOL_GPL(ata_pci_device_suspend); int ata_pci_device_resume(struct pci_dev *pdev) { @@ -6850,8 +6925,8 @@ int ata_pci_device_resume(struct pci_dev *pdev) ata_host_resume(host); return rc; } +EXPORT_SYMBOL_GPL(ata_pci_device_resume); #endif /* CONFIG_PM */ - #endif /* CONFIG_PCI */ /** @@ -6873,6 +6948,7 @@ int ata_platform_remove_one(struct platform_device *pdev) return 0; } +EXPORT_SYMBOL_GPL(ata_platform_remove_one); static int __init ata_parse_force_one(char **cur, struct ata_force_ent *force_ent, @@ -7097,6 +7173,7 @@ int ata_ratelimit(void) { return __ratelimit(&ratelimit); } +EXPORT_SYMBOL_GPL(ata_ratelimit); /** * ata_msleep - ATA EH owner aware msleep @@ -7129,6 +7206,7 @@ void ata_msleep(struct ata_port *ap, unsigned int msecs) if (owns_eh) ata_eh_acquire(ap); } +EXPORT_SYMBOL_GPL(ata_msleep); /** * ata_wait_register - wait until register value changes @@ -7175,6 +7253,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, return tmp; } +EXPORT_SYMBOL_GPL(ata_wait_register); /** * sata_lpm_ignore_phy_events - test if PHY event should be ignored @@ -7228,10 +7307,12 @@ struct ata_port_operations ata_dummy_port_ops = { .sched_eh = ata_std_sched_eh, .end_eh = ata_std_end_eh, }; +EXPORT_SYMBOL_GPL(ata_dummy_port_ops); const struct ata_port_info ata_dummy_port_info = { .port_ops = &ata_dummy_port_ops, }; +EXPORT_SYMBOL_GPL(ata_dummy_port_info); /* * Utility print functions @@ -7299,126 +7380,3 @@ void ata_print_version(const struct device *dev, const char *version) dev_printk(KERN_DEBUG, dev, "version %s\n", version); } EXPORT_SYMBOL(ata_print_version); - -/* - * libata is essentially a library of internal helper functions for - * low-level ATA host controller drivers. As such, the API/ABI is - * likely to change as new drivers are added and updated. - * Do not depend on ABI/API stability. - */ -EXPORT_SYMBOL_GPL(sata_deb_timing_normal); -EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); -EXPORT_SYMBOL_GPL(sata_deb_timing_long); -EXPORT_SYMBOL_GPL(ata_base_port_ops); -EXPORT_SYMBOL_GPL(sata_port_ops); -EXPORT_SYMBOL_GPL(ata_dummy_port_ops); -EXPORT_SYMBOL_GPL(ata_dummy_port_info); -EXPORT_SYMBOL_GPL(ata_link_next); -EXPORT_SYMBOL_GPL(ata_dev_next); -EXPORT_SYMBOL_GPL(ata_std_bios_param); -EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); -EXPORT_SYMBOL_GPL(ata_host_init); -EXPORT_SYMBOL_GPL(ata_host_alloc); -EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); -EXPORT_SYMBOL_GPL(ata_slave_link_init); -EXPORT_SYMBOL_GPL(ata_host_start); -EXPORT_SYMBOL_GPL(ata_host_register); -EXPORT_SYMBOL_GPL(ata_host_activate); -EXPORT_SYMBOL_GPL(ata_host_detach); -EXPORT_SYMBOL_GPL(ata_sg_init); -EXPORT_SYMBOL_GPL(ata_qc_complete); -EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); -EXPORT_SYMBOL_GPL(atapi_cmd_type); -EXPORT_SYMBOL_GPL(ata_tf_to_fis); -EXPORT_SYMBOL_GPL(ata_tf_from_fis); -EXPORT_SYMBOL_GPL(ata_pack_xfermask); -EXPORT_SYMBOL_GPL(ata_unpack_xfermask); -EXPORT_SYMBOL_GPL(ata_xfer_mask2mode); -EXPORT_SYMBOL_GPL(ata_xfer_mode2mask); -EXPORT_SYMBOL_GPL(ata_xfer_mode2shift); -EXPORT_SYMBOL_GPL(ata_mode_string); -EXPORT_SYMBOL_GPL(ata_id_xfermask); -EXPORT_SYMBOL_GPL(ata_do_set_mode); -EXPORT_SYMBOL_GPL(ata_std_qc_defer); -EXPORT_SYMBOL_GPL(ata_noop_qc_prep); -EXPORT_SYMBOL_GPL(ata_dev_disable); -EXPORT_SYMBOL_GPL(sata_set_spd); -EXPORT_SYMBOL_GPL(ata_wait_after_reset); -EXPORT_SYMBOL_GPL(sata_link_debounce); -EXPORT_SYMBOL_GPL(sata_link_resume); -EXPORT_SYMBOL_GPL(sata_link_scr_lpm); -EXPORT_SYMBOL_GPL(ata_std_prereset); -EXPORT_SYMBOL_GPL(sata_link_hardreset); -EXPORT_SYMBOL_GPL(sata_std_hardreset); -EXPORT_SYMBOL_GPL(ata_std_postreset); -EXPORT_SYMBOL_GPL(ata_dev_classify); -EXPORT_SYMBOL_GPL(ata_dev_pair); -EXPORT_SYMBOL_GPL(ata_ratelimit); -EXPORT_SYMBOL_GPL(ata_msleep); -EXPORT_SYMBOL_GPL(ata_wait_register); -EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); -EXPORT_SYMBOL_GPL(ata_scsi_slave_config); -EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); -EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); -EXPORT_SYMBOL_GPL(__ata_change_queue_depth); -EXPORT_SYMBOL_GPL(sata_scr_valid); -EXPORT_SYMBOL_GPL(sata_scr_read); -EXPORT_SYMBOL_GPL(sata_scr_write); -EXPORT_SYMBOL_GPL(sata_scr_write_flush); -EXPORT_SYMBOL_GPL(ata_link_online); -EXPORT_SYMBOL_GPL(ata_link_offline); -#ifdef CONFIG_PM -EXPORT_SYMBOL_GPL(ata_host_suspend); -EXPORT_SYMBOL_GPL(ata_host_resume); -#endif /* CONFIG_PM */ -EXPORT_SYMBOL_GPL(ata_id_string); -EXPORT_SYMBOL_GPL(ata_id_c_string); -EXPORT_SYMBOL_GPL(ata_do_dev_read_id); -EXPORT_SYMBOL_GPL(ata_scsi_simulate); - -EXPORT_SYMBOL_GPL(ata_pio_need_iordy); -EXPORT_SYMBOL_GPL(ata_timing_find_mode); -EXPORT_SYMBOL_GPL(ata_timing_compute); -EXPORT_SYMBOL_GPL(ata_timing_merge); -EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); - -#ifdef CONFIG_PCI -EXPORT_SYMBOL_GPL(pci_test_config_bits); -EXPORT_SYMBOL_GPL(ata_pci_remove_one); -#ifdef CONFIG_PM -EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend); -EXPORT_SYMBOL_GPL(ata_pci_device_do_resume); -EXPORT_SYMBOL_GPL(ata_pci_device_suspend); -EXPORT_SYMBOL_GPL(ata_pci_device_resume); -#endif /* CONFIG_PM */ -#endif /* CONFIG_PCI */ - -EXPORT_SYMBOL_GPL(ata_platform_remove_one); - -EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); -EXPORT_SYMBOL_GPL(ata_port_desc); -#ifdef CONFIG_PCI -EXPORT_SYMBOL_GPL(ata_port_pbar_desc); -#endif /* CONFIG_PCI */ -EXPORT_SYMBOL_GPL(ata_port_schedule_eh); -EXPORT_SYMBOL_GPL(ata_link_abort); -EXPORT_SYMBOL_GPL(ata_port_abort); -EXPORT_SYMBOL_GPL(ata_port_freeze); -EXPORT_SYMBOL_GPL(sata_async_notification); -EXPORT_SYMBOL_GPL(ata_eh_freeze_port); -EXPORT_SYMBOL_GPL(ata_eh_thaw_port); -EXPORT_SYMBOL_GPL(ata_eh_qc_complete); -EXPORT_SYMBOL_GPL(ata_eh_qc_retry); -EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); -EXPORT_SYMBOL_GPL(ata_do_eh); -EXPORT_SYMBOL_GPL(ata_std_error_handler); - -EXPORT_SYMBOL_GPL(ata_cable_40wire); -EXPORT_SYMBOL_GPL(ata_cable_80wire); -EXPORT_SYMBOL_GPL(ata_cable_unknown); -EXPORT_SYMBOL_GPL(ata_cable_ignore); -EXPORT_SYMBOL_GPL(ata_cable_sata); -EXPORT_SYMBOL_GPL(ata_host_get); -EXPORT_SYMBOL_GPL(ata_host_put); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 53605c8949d8..1d231cfab26f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -180,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) __ata_ehi_pushv_desc(ehi, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); /** * ata_ehi_push_desc - push error description with separator @@ -203,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) __ata_ehi_pushv_desc(ehi, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(ata_ehi_push_desc); /** * ata_ehi_clear_desc - clean error description @@ -218,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi) ehi->desc[0] = '\0'; ehi->desc_len = 0; } +EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); /** * ata_port_desc - append port description @@ -245,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...) __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(ata_port_desc); #ifdef CONFIG_PCI - /** * ata_port_pbar_desc - append PCI BAR description * @ap: target ATA port @@ -284,7 +287,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, ata_port_desc(ap, "%s 0x%llx", name, start + (unsigned long long)offset); } - +EXPORT_SYMBOL_GPL(ata_port_pbar_desc); #endif /* CONFIG_PCI */ static int ata_lookup_timeout_table(u8 cmd) @@ -969,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap) /* see: ata_std_sched_eh, unless you know better */ ap->ops->sched_eh(ap); } +EXPORT_SYMBOL_GPL(ata_port_schedule_eh); static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) { @@ -1011,6 +1015,7 @@ int ata_link_abort(struct ata_link *link) { return ata_do_link_abort(link->ap, link); } +EXPORT_SYMBOL_GPL(ata_link_abort); /** * ata_port_abort - abort all qc's on the port @@ -1028,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap) { return ata_do_link_abort(ap, NULL); } +EXPORT_SYMBOL_GPL(ata_port_abort); /** * __ata_port_freeze - freeze port @@ -1084,6 +1090,7 @@ int ata_port_freeze(struct ata_port *ap) return nr_aborted; } +EXPORT_SYMBOL_GPL(ata_port_freeze); /** * sata_async_notification - SATA async notification handler @@ -1157,6 +1164,7 @@ int sata_async_notification(struct ata_port *ap) return 0; } } +EXPORT_SYMBOL_GPL(sata_async_notification); /** * ata_eh_freeze_port - EH helper to freeze port @@ -1178,6 +1186,7 @@ void ata_eh_freeze_port(struct ata_port *ap) __ata_port_freeze(ap); spin_unlock_irqrestore(ap->lock, flags); } +EXPORT_SYMBOL_GPL(ata_eh_freeze_port); /** * ata_port_thaw_port - EH helper to thaw port @@ -1206,6 +1215,7 @@ void ata_eh_thaw_port(struct ata_port *ap) DPRINTK("ata%u port thawed\n", ap->print_id); } +EXPORT_SYMBOL_GPL(ata_eh_thaw_port); static void ata_eh_scsidone(struct scsi_cmnd *scmd) { @@ -1240,6 +1250,7 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc) scmd->retries = scmd->allowed; __ata_eh_qc_complete(qc); } +EXPORT_SYMBOL_GPL(ata_eh_qc_complete); /** * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH @@ -1259,6 +1270,7 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) scmd->allowed++; __ata_eh_qc_complete(qc); } +EXPORT_SYMBOL_GPL(ata_eh_qc_retry); /** * ata_dev_disable - disable ATA device @@ -1285,6 +1297,7 @@ void ata_dev_disable(struct ata_device *dev) */ ata_ering_clear(&dev->ering); } +EXPORT_SYMBOL_GPL(ata_dev_disable); /** * ata_eh_detach_dev - detach ATA device @@ -1727,6 +1740,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ehc->i.err_mask &= ~AC_ERR_DEV; } +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); /** * ata_eh_analyze_tf - analyze taskfile of a failed qc @@ -4027,6 +4041,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } +EXPORT_SYMBOL_GPL(ata_do_eh); /** * ata_std_error_handler - standard error handler @@ -4048,6 +4063,7 @@ void ata_std_error_handler(struct ata_port *ap) ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); } +EXPORT_SYMBOL_GPL(ata_std_error_handler); #ifdef CONFIG_PM /** diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cc8ba49275e7..321b5a1d610a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -501,6 +501,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, return 0; } +EXPORT_SYMBOL_GPL(ata_std_bios_param); /** * ata_scsi_unlock_native_capacity - unlock native capacity @@ -530,6 +531,7 @@ void ata_scsi_unlock_native_capacity(struct scsi_device *sdev) spin_unlock_irqrestore(ap->lock, flags); ata_port_wait_eh(ap); } +EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); /** * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl @@ -1346,6 +1348,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev) return rc; } +EXPORT_SYMBOL_GPL(ata_scsi_slave_config); /** * ata_scsi_slave_destroy - SCSI device is about to be destroyed @@ -1385,6 +1388,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) q->dma_drain_buffer = NULL; q->dma_drain_size = 0; } +EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); /** * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth @@ -1428,6 +1432,7 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, return scsi_change_queue_depth(sdev, queue_depth); } +EXPORT_SYMBOL_GPL(__ata_change_queue_depth); /** * ata_scsi_change_queue_depth - SCSI callback for queue depth config @@ -1450,6 +1455,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) return __ata_change_queue_depth(ap, sdev, queue_depth); } +EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); /** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command @@ -4405,6 +4411,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) return rc; } +EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); /** * ata_scsi_simulate - simulate SCSI command on ATA device @@ -4528,6 +4535,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } +EXPORT_SYMBOL_GPL(ata_scsi_simulate); int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) { -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 08/28] ata: move EXPORT_SYMBOL_GPL()s close to exported code 2020-01-28 13:33 ` [PATCH 08/28] ata: move EXPORT_SYMBOL_GPL()s close to exported code Bartlomiej Zolnierkiewicz @ 2020-01-29 17:18 ` Christoph Hellwig 0 siblings, 0 replies; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:18 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:23PM +0100, Bartlomiej Zolnierkiewicz wrote: > Move EXPORT_SYMBOL_GPL()s close to exported code like it is > done in other kernel subsystems. As a nice side effect this > results in the removal of few ifdefs. > > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133413eucas1p1725ccae03fb5aba49f0e0cef798da9d6@eucas1p1.samsung.com>]
* [PATCH 09/28] ata: remove EXPORT_SYMBOL_GPL()s not used by modules [not found] ` <CGME20200128133413eucas1p1725ccae03fb5aba49f0e0cef798da9d6@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:19 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Remove EXPORT_SYMBOL_GPL()s for functions used only by the core libata code. Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 39838 573 40 40451 9e03 drivers/ata/libata-core.o 21071 105 4096 25272 62b8 drivers/ata/libata-scsi.o 17519 18 0 17537 4481 drivers/ata/libata-eh.o after: 39688 573 40 40301 9d6d drivers/ata/libata-core.o 21040 105 4096 25241 6299 drivers/ata/libata-scsi.o 17405 18 0 17423 440f drivers/ata/libata-eh.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core.c | 5 ----- drivers/ata/libata-eh.c | 4 ---- drivers/ata/libata-scsi.c | 1 - 3 files changed, 10 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ad724602c47c..c41198bb9582 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -80,7 +80,6 @@ const struct ata_port_operations ata_base_port_ops = { .sched_eh = ata_std_sched_eh, .end_eh = ata_std_end_eh, }; -EXPORT_SYMBOL_GPL(ata_base_port_ops); const struct ata_port_operations sata_port_ops = { .inherits = &ata_base_port_ops, @@ -902,7 +901,6 @@ void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask, if (udma_mask) *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; } -EXPORT_SYMBOL_GPL(ata_unpack_xfermask); static const struct ata_xfer_ent { int shift, bits; @@ -3425,7 +3423,6 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } -EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); /** * ata_down_xfermask_limit - adjust dev xfer masks downward @@ -5051,7 +5048,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->n_elem = n_elem; qc->cursg = qc->sg; } -EXPORT_SYMBOL_GPL(ata_sg_init); #ifdef CONFIG_HAS_DMA @@ -6157,7 +6153,6 @@ void ata_host_get(struct ata_host *host) { kref_get(&host->kref); } -EXPORT_SYMBOL_GPL(ata_host_get); void ata_host_put(struct ata_host *host) { diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1d231cfab26f..04275f4c8d36 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1215,7 +1215,6 @@ void ata_eh_thaw_port(struct ata_port *ap) DPRINTK("ata%u port thawed\n", ap->print_id); } -EXPORT_SYMBOL_GPL(ata_eh_thaw_port); static void ata_eh_scsidone(struct scsi_cmnd *scmd) { @@ -1250,7 +1249,6 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc) scmd->retries = scmd->allowed; __ata_eh_qc_complete(qc); } -EXPORT_SYMBOL_GPL(ata_eh_qc_complete); /** * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH @@ -1270,7 +1268,6 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) scmd->allowed++; __ata_eh_qc_complete(qc); } -EXPORT_SYMBOL_GPL(ata_eh_qc_retry); /** * ata_dev_disable - disable ATA device @@ -4041,7 +4038,6 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } -EXPORT_SYMBOL_GPL(ata_do_eh); /** * ata_std_error_handler - standard error handler diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 321b5a1d610a..d549bd5b3d36 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4535,7 +4535,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } -EXPORT_SYMBOL_GPL(ata_scsi_simulate); int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) { -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 09/28] ata: remove EXPORT_SYMBOL_GPL()s not used by modules 2020-01-28 13:33 ` [PATCH 09/28] ata: remove EXPORT_SYMBOL_GPL()s not used by modules Bartlomiej Zolnierkiewicz @ 2020-01-29 17:19 ` Christoph Hellwig 0 siblings, 0 replies; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:19 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133414eucas1p14b041a2d58ca70817f3007c0f405ee73@eucas1p1.samsung.com>]
* [PATCH 10/28] ata: separate PATA timings code from libata-core.c [not found] ` <CGME20200128133414eucas1p14b041a2d58ca70817f3007c0f405ee73@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:23 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Separate PATA timings code from libata-core.c: * add PATA_TIMINGS config option and make corresponding PATA host drivers (and ATA ACPI code) select it * move following PATA timings code to libata-pata-timings.c: - ata_timing_quantize() - ata_timing_merge() - ata_timing_find_mode() - ata_timing_compute() * group above functions together in <linux/libata.h> and cover them with CONFIG_PATA_TIMINGS ifdef * include libata-pata-timings.c in the build when PATA_TIMINGS config option is enabled * cover ata_timing_cycle2mode() with CONFIG_ATA_ACPI ifdef (it depends on code from libata-core.c and libata-pata-timings.c while its only user is ATA ACPI) Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 39688 573 40 40301 9d6d drivers/ata/libata-core.o after: 37820 572 40 38432 9620 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/Kconfig | 21 ++++ drivers/ata/Makefile | 1 + drivers/ata/libata-core.c | 171 +--------------------------- drivers/ata/libata-pata-timings.c | 180 ++++++++++++++++++++++++++++++ include/linux/libata.h | 20 +++- 5 files changed, 218 insertions(+), 175 deletions(-) create mode 100644 drivers/ata/libata-pata-timings.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ad7760656f71..5b55ebf56b5a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -37,6 +37,9 @@ config ATA_NONSTANDARD config SATA_HOST bool +config PATA_TIMINGS + bool + config ATA_VERBOSE_ERROR bool "Verbose ATA error reporting" default y @@ -51,6 +54,7 @@ config ATA_VERBOSE_ERROR config ATA_ACPI bool "ATA ACPI Support" depends on ACPI + select PATA_TIMINGS default y help This option adds support for ATA-related ACPI objects. @@ -341,6 +345,7 @@ config PDC_ADMA config PATA_OCTEON_CF tristate "OCTEON Boot Bus Compact Flash support" depends on CAVIUM_OCTEON_SOC + select PATA_TIMINGS help This option enables a polled compact flash driver for use with compact flash cards attached to the OCTEON boot bus. @@ -536,6 +541,7 @@ comment "PATA SFF controllers with BMDMA" config PATA_ALI tristate "ALi PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the ALi ATA interfaces found on the many ALi chipsets. @@ -545,6 +551,7 @@ config PATA_ALI config PATA_AMD tristate "AMD/NVidia PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the AMD and NVidia PATA interfaces found on the chipsets for Athlon/Athlon64. @@ -579,6 +586,7 @@ config PATA_ATIIXP config PATA_ATP867X tristate "ARTOP/Acard ATP867X PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for ARTOP/Acard ATP867X PATA controllers. @@ -588,6 +596,7 @@ config PATA_ATP867X config PATA_BK3710 tristate "Palmchip BK3710 PATA support" depends on ARCH_DAVINCI + select PATA_TIMINGS help This option enables support for the integrated IDE controller on the TI DaVinci SoC. @@ -597,6 +606,7 @@ config PATA_BK3710 config PATA_CMD64X tristate "CMD64x PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the CMD64x series chips except for the CMD640. @@ -642,6 +652,7 @@ config PATA_CS5536 config PATA_CYPRESS tristate "Cypress CY82C693 PATA support (Very Experimental)" depends on PCI + select PATA_TIMINGS help This option enables support for the Cypress/Contaq CY82C693 chipset found in some Alpha systems @@ -660,6 +671,7 @@ config PATA_EFAR config PATA_EP93XX tristate "Cirrus Logic EP93xx PATA support" depends on ARCH_EP93XX + select PATA_TIMINGS help This option enables support for the PATA controller in the Cirrus Logic EP9312 and EP9315 ARM CPU. @@ -724,6 +736,7 @@ config PATA_HPT3X3_DMA config PATA_ICSIDE tristate "Acorn ICS PATA support" depends on ARM && ARCH_ACORN + select PATA_TIMINGS help On Acorn systems, say Y here if you wish to use the ICS PATA interface card. This is not required for ICS partition support. @@ -732,6 +745,7 @@ config PATA_ICSIDE config PATA_IMX tristate "PATA support for Freescale iMX" depends on ARCH_MXC + select PATA_TIMINGS help This option enables support for the PATA host available on Freescale iMX SoCs. @@ -817,6 +831,7 @@ config PATA_NINJA32 config PATA_NS87415 tristate "Nat Semi NS87415 PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the National Semiconductor NS87415 PCI-IDE controller. @@ -941,6 +956,7 @@ config PATA_TRIFLEX config PATA_VIA tristate "VIA PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the VIA PATA interfaces found on the many VIA chipsets. @@ -974,6 +990,7 @@ comment "PIO-only SFF controllers" config PATA_CMD640_PCI tristate "CMD640 PCI PATA support (Experimental)" depends on PCI + select PATA_TIMINGS help This option enables support for the CMD640 PCI IDE interface chip. Only the primary channel is currently @@ -1044,6 +1061,7 @@ config PATA_MPIIX config PATA_NS87410 tristate "Nat Semi NS87410 PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the National Semiconductor NS87410 PCI-IDE controller. @@ -1124,6 +1142,7 @@ config PATA_RZ1000 config PATA_SAMSUNG_CF tristate "Samsung SoC PATA support" depends on SAMSUNG_DEV_IDE + select PATA_TIMINGS help This option enables basic support for Samsung's S3C/S5P board PATA controllers via the new ATA layer @@ -1143,6 +1162,7 @@ comment "Generic fallback / legacy drivers" config PATA_ACPI tristate "ACPI firmware driver for PATA" depends on ATA_ACPI && ATA_BMDMA && PCI + select PATA_TIMINGS help This option enables an ACPI method driver which drives motherboard PATA controller interfaces through the ACPI @@ -1162,6 +1182,7 @@ config ATA_GENERIC config PATA_LEGACY tristate "Legacy ISA PATA support (Experimental)" depends on (ISA || PCI) + select PATA_TIMINGS help This option enables support for ISA/VLB/PCI bus legacy PATA ports and allows them to be accessed via the new ATA layer. diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d8cc2e04a6c7..cdaf965fed25 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -127,3 +127,4 @@ libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o +libata-$(CONFIG_PATA_TIMINGS) += libata-pata-timings.o diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c41198bb9582..408dee580f24 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3204,175 +3204,7 @@ int sata_set_spd(struct ata_link *link) } EXPORT_SYMBOL_GPL(sata_set_spd); -/* - * This mode timing computation functionality is ported over from - * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik - */ -/* - * PIO 0-4, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). - * These were taken from ATA/ATAPI-6 standard, rev 0a, except - * for UDMA6, which is currently supported only by Maxtor drives. - * - * For PIO 5/6 MWDMA 3/4 see the CFA specification 3.0. - */ - -static const struct ata_timing ata_timing[] = { -/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */ - { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 }, - { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 }, - { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 }, - { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 }, - { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 }, - { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 }, - { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 }, - - { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 }, - { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 }, - { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 }, - - { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 }, - { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 }, - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 }, - { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 }, - { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 }, - -/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */ - { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 }, - { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 }, - { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 }, - { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 }, - { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 }, - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 }, - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 }, - - { 0xFF } -}; - -#define ENOUGH(v, unit) (((v)-1)/(unit)+1) -#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0) - -static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) -{ - q->setup = EZ(t->setup, T); - q->act8b = EZ(t->act8b, T); - q->rec8b = EZ(t->rec8b, T); - q->cyc8b = EZ(t->cyc8b, T); - q->active = EZ(t->active, T); - q->recover = EZ(t->recover, T); - q->dmack_hold = EZ(t->dmack_hold, T); - q->cycle = EZ(t->cycle, T); - q->udma = EZ(t->udma, UT); -} - -void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, - struct ata_timing *m, unsigned int what) -{ - if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup); - if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); - if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); - if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); - if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); - if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); - if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold); - if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); - if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); -} -EXPORT_SYMBOL_GPL(ata_timing_merge); - -const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) -{ - const struct ata_timing *t = ata_timing; - - while (xfer_mode > t->mode) - t++; - - if (xfer_mode == t->mode) - return t; - - WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", - __func__, xfer_mode); - - return NULL; -} -EXPORT_SYMBOL_GPL(ata_timing_find_mode); - -int ata_timing_compute(struct ata_device *adev, unsigned short speed, - struct ata_timing *t, int T, int UT) -{ - const u16 *id = adev->id; - const struct ata_timing *s; - struct ata_timing p; - - /* - * Find the mode. - */ - - if (!(s = ata_timing_find_mode(speed))) - return -EINVAL; - - memcpy(t, s, sizeof(*s)); - - /* - * If the drive is an EIDE drive, it can tell us it needs extended - * PIO/MW_DMA cycle timing. - */ - - if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ - memset(&p, 0, sizeof(p)); - - if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) { - if (speed <= XFER_PIO_2) - p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; - else if ((speed <= XFER_PIO_4) || - (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) - p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; - } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) - p.cycle = id[ATA_ID_EIDE_DMA_MIN]; - - ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); - } - - /* - * Convert the timing to bus clock counts. - */ - - ata_timing_quantize(t, t, T, UT); - - /* - * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, - * S.M.A.R.T * and some other commands. We have to ensure that the - * DMA cycle timing is slower/equal than the fastest PIO timing. - */ - - if (speed > XFER_PIO_6) { - ata_timing_compute(adev, adev->pio_mode, &p, T, UT); - ata_timing_merge(&p, t, t, ATA_TIMING_ALL); - } - - /* - * Lengthen active & recovery time so that cycle time is correct. - */ - - if (t->act8b + t->rec8b < t->cyc8b) { - t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; - t->rec8b = t->cyc8b - t->act8b; - } - - if (t->active + t->recover < t->cycle) { - t->active += (t->cycle - (t->active + t->recover)) / 2; - t->recover = t->cycle - t->active; - } - - /* In a few cases quantisation may produce enough errors to - leave t->cycle too low for the sum of active and recovery - if so we must correct this */ - if (t->active + t->recover > t->cycle) - t->cycle = t->active + t->recover; - - return 0; -} -EXPORT_SYMBOL_GPL(ata_timing_compute); - +#ifdef CONFIG_ATA_ACPI /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration * @xfer_shift: ATA_SHIFT_* value for transfer type to examine. @@ -3423,6 +3255,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } +#endif /** * ata_down_xfermask_limit - adjust dev xfer masks downward diff --git a/drivers/ata/libata-pata-timings.c b/drivers/ata/libata-pata-timings.c new file mode 100644 index 000000000000..bababa6f519b --- /dev/null +++ b/drivers/ata/libata-pata-timings.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * libata-pata-timings.c - helper library for PATA timings + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/libata.h> + +/* + * This mode timing computation functionality is ported over from + * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik + */ +/* + * PIO 0-4, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). + * These were taken from ATA/ATAPI-6 standard, rev 0a, except + * for UDMA6, which is currently supported only by Maxtor drives. + * + * For PIO 5/6 MWDMA 3/4 see the CFA specification 3.0. + */ + +static const struct ata_timing ata_timing[] = { +/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */ + { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 }, + { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 }, + { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 }, + { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 }, + { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 }, + { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 }, + { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 }, + + { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 }, + { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 }, + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 }, + + { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 }, + { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 }, + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 }, + { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 }, + { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 }, + +/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */ + { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 }, + { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 }, + { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 }, + { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 }, + { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 }, + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 }, + + { 0xFF } +}; + +#define ENOUGH(v, unit) (((v)-1)/(unit)+1) +#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0) + +static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) +{ + q->setup = EZ(t->setup, T); + q->act8b = EZ(t->act8b, T); + q->rec8b = EZ(t->rec8b, T); + q->cyc8b = EZ(t->cyc8b, T); + q->active = EZ(t->active, T); + q->recover = EZ(t->recover, T); + q->dmack_hold = EZ(t->dmack_hold, T); + q->cycle = EZ(t->cycle, T); + q->udma = EZ(t->udma, UT); +} + +void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, + struct ata_timing *m, unsigned int what) +{ + if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup); + if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); + if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); + if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); + if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); + if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); + if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold); + if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); + if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); +} +EXPORT_SYMBOL_GPL(ata_timing_merge); + +const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) +{ + const struct ata_timing *t = ata_timing; + + while (xfer_mode > t->mode) + t++; + + if (xfer_mode == t->mode) + return t; + + WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", + __func__, xfer_mode); + + return NULL; +} +EXPORT_SYMBOL_GPL(ata_timing_find_mode); + +int ata_timing_compute(struct ata_device *adev, unsigned short speed, + struct ata_timing *t, int T, int UT) +{ + const u16 *id = adev->id; + const struct ata_timing *s; + struct ata_timing p; + + /* + * Find the mode. + */ + + if (!(s = ata_timing_find_mode(speed))) + return -EINVAL; + + memcpy(t, s, sizeof(*s)); + + /* + * If the drive is an EIDE drive, it can tell us it needs extended + * PIO/MW_DMA cycle timing. + */ + + if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ + memset(&p, 0, sizeof(p)); + + if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) { + if (speed <= XFER_PIO_2) + p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; + else if ((speed <= XFER_PIO_4) || + (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) + p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; + } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) + p.cycle = id[ATA_ID_EIDE_DMA_MIN]; + + ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); + } + + /* + * Convert the timing to bus clock counts. + */ + + ata_timing_quantize(t, t, T, UT); + + /* + * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, + * S.M.A.R.T * and some other commands. We have to ensure that the + * DMA cycle timing is slower/equal than the fastest PIO timing. + */ + + if (speed > XFER_PIO_6) { + ata_timing_compute(adev, adev->pio_mode, &p, T, UT); + ata_timing_merge(&p, t, t, ATA_TIMING_ALL); + } + + /* + * Lengthen active & recovery time so that cycle time is correct. + */ + + if (t->act8b + t->rec8b < t->cyc8b) { + t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; + t->rec8b = t->cyc8b - t->act8b; + } + + if (t->active + t->recover < t->cycle) { + t->active += (t->cycle - (t->active + t->recover)) / 2; + t->recover = t->cycle - t->active; + } + + /* In a few cases quantisation may produce enough errors to + leave t->cycle too low for the sum of active and recovery + if so we must correct this */ + if (t->active + t->recover > t->cycle) + t->cycle = t->active + t->recover; + + return 0; +} +EXPORT_SYMBOL_GPL(ata_timing_compute); diff --git a/include/linux/libata.h b/include/linux/libata.h index dc162cca63a4..79953c6d769c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1207,13 +1207,9 @@ extern int ata_cable_unknown(struct ata_port *ap); /* Timing helpers */ extern unsigned int ata_pio_need_iordy(const struct ata_device *); -extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode); -extern int ata_timing_compute(struct ata_device *, unsigned short, - struct ata_timing *, int, int); -extern void ata_timing_merge(const struct ata_timing *, - const struct ata_timing *, struct ata_timing *, - unsigned int); +#ifdef CONFIG_ATA_ACPI extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); +#endif /* PCI */ #ifdef CONFIG_PCI @@ -1805,6 +1801,18 @@ static inline int ata_dma_enabled(struct ata_device *adev) return (adev->dma_mode == 0xFF ? 0 : 1); } +/************************************************************************** + * PATA timings - drivers/ata/libata-pata-timings.c + */ +#ifdef CONFIG_PATA_TIMINGS +extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode); +extern int ata_timing_compute(struct ata_device *, unsigned short, + struct ata_timing *, int, int); +extern void ata_timing_merge(const struct ata_timing *, + const struct ata_timing *, struct ata_timing *, + unsigned int); +#endif + /************************************************************************** * PMP - drivers/ata/libata-pmp.c */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 10/28] ata: separate PATA timings code from libata-core.c 2020-01-28 13:33 ` [PATCH 10/28] ata: separate PATA timings code from libata-core.c Bartlomiej Zolnierkiewicz @ 2020-01-29 17:23 ` Christoph Hellwig 2020-02-07 14:20 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:23 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * libata-pata-timings.c - helper library for PATA timings Please remove the file name from the top of the file header. > +static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) > +{ > +void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, > + struct ata_timing *m, unsigned int what) > +{ Please fix the overly long lines while you're at it. > + if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup); > + if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); > + if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); > + if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); > + if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); > + if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); > + if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold); > + if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); > + if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); and this very strange coding style. > + if (!(s = ata_timing_find_mode(speed))) > + return -EINVAL; This should be: s = ata_timing_find_mode(speed); if (!s) return -EINVAL; > + /* In a few cases quantisation may produce enough errors to > + leave t->cycle too low for the sum of active and recovery > + if so we must correct this */ .. non-standard comment style here. > +#ifdef CONFIG_ATA_ACPI > extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); > +#endif I don't think we need this ifdef - unused prototypes are completely harmless. ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 10/28] ata: separate PATA timings code from libata-core.c 2020-01-29 17:23 ` Christoph Hellwig @ 2020-02-07 14:20 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:20 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:23 PM, Christoph Hellwig wrote: >> +// SPDX-License-Identifier: GPL-2.0-or-later >> +/* >> + * libata-pata-timings.c - helper library for PATA timings > > Please remove the file name from the top of the file header. > >> +static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) >> +{ > >> +void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, >> + struct ata_timing *m, unsigned int what) >> +{ > > Please fix the overly long lines while you're at it. > >> + if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup); >> + if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); >> + if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); >> + if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); >> + if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); >> + if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); >> + if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold); >> + if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); >> + if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); > > and this very strange coding style. > >> + if (!(s = ata_timing_find_mode(speed))) >> + return -EINVAL; > > This should be: > > s = ata_timing_find_mode(speed); > if (!s) > return -EINVAL; > >> + /* In a few cases quantisation may produce enough errors to >> + leave t->cycle too low for the sum of active and recovery >> + if so we must correct this */ > > .. non-standard comment style here. I've added additional patch in v2 version of the patchset fixing above CodingStyle issues in PATA timings code in libata-core.c (just before the code gets separated to libata-pata-timings.c). >> +#ifdef CONFIG_ATA_ACPI >> extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); >> +#endif > > I don't think we need this ifdef - unused prototypes are completely > harmless. Fixed in v2 version of the patch. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133414eucas1p1c69ee66d4799a5aea22561b42ab73e11@eucas1p1.samsung.com>]
* [PATCH 11/28] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() [not found] ` <CGME20200128133414eucas1p1c69ee66d4799a5aea22561b42ab73e11@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:24 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie When CONFIG_SATA_HOST=n there are no NCQ capable host drivers built so it is safe to hardwire ata_ncq_enabled() to always return zero. Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 37820 572 40 38432 9620 drivers/ata/libata-core.o 21040 105 4096 25241 6299 drivers/ata/libata-scsi.o 17405 18 0 17423 440f drivers/ata/libata-eh.o after: 37582 572 40 38194 9532 drivers/ata/libata-core.o 20702 105 4096 24903 6147 drivers/ata/libata-scsi.o 17353 18 0 17371 43db drivers/ata/libata-eh.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- include/linux/libata.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/libata.h b/include/linux/libata.h index 79953c6d769c..5b7bed18f56e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1633,8 +1633,12 @@ extern struct ata_device *ata_dev_next(struct ata_device *dev, */ static inline int ata_ncq_enabled(struct ata_device *dev) { +#ifdef CONFIG_SATA_HOST return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; +#else + return 0; +#endif } static inline bool ata_fpdma_dsm_supported(struct ata_device *dev) -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 11/28] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() 2020-01-28 13:33 ` [PATCH 11/28] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() Bartlomiej Zolnierkiewicz @ 2020-01-29 17:24 ` Christoph Hellwig 2020-02-07 14:21 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:24 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel > static inline int ata_ncq_enabled(struct ata_device *dev) > { > +#ifdef CONFIG_SATA_HOST > return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | > ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; > +#else > + return 0; > +#endif I think this is a prime candidate for IS_ENABLED: if (!IS_ENABLED(CONFIG_SATA_HOST)) return 0; return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 11/28] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() 2020-01-29 17:24 ` Christoph Hellwig @ 2020-02-07 14:21 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:21 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:24 PM, Christoph Hellwig wrote: >> static inline int ata_ncq_enabled(struct ata_device *dev) >> { >> +#ifdef CONFIG_SATA_HOST >> return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | >> ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; >> +#else >> + return 0; >> +#endif > > I think this is a prime candidate for IS_ENABLED: > > if (!IS_ENABLED(CONFIG_SATA_HOST)) > return 0; > return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | > ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; > Fully agreed, fixed in v2. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133414eucas1p2baefeb1a492375b18bdf6cdfbd0db796@eucas1p2.samsung.com>]
* [PATCH 12/28] ata: start separating SATA specific code from libata-core.c [not found] ` <CGME20200128133414eucas1p2baefeb1a492375b18bdf6cdfbd0db796@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:26 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Start separating SATA specific code from libata-core.c: * move following functions to libata-core-sata.c: - ata_tf_to_fis() - ata_tf_from_fis() - sata_link_scr_lpm() - ata_slave_link_init() - sata_lpm_ignore_phy_events() * group above functions together in <linux/libata.h> and cover them with CONFIG_SATA_HOST ifdef * include libata-core-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: 37582 572 40 38194 9532 drivers/ata/libata-core.o after: 36762 572 40 37374 91fe drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/Makefile | 1 + drivers/ata/libata-core-sata.c | 258 +++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 245 ------------------------------- include/linux/libata.h | 18 ++- 4 files changed, 271 insertions(+), 251 deletions(-) create mode 100644 drivers/ata/libata-core-sata.c diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index cdaf965fed25..b06b9a211691 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -123,6 +123,7 @@ 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-$(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-core-sata.c b/drivers/ata/libata-core-sata.c new file mode 100644 index 000000000000..8b939d2db0a6 --- /dev/null +++ b/drivers/ata/libata-core-sata.c @@ -0,0 +1,258 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * libata-core-sata.c - SATA specific part of ATA helper library + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/libata.h> + +#include "libata.h" + +/** + * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure + * @tf: Taskfile to convert + * @pmp: Port multiplier port + * @is_cmd: This FIS is for command + * @fis: Buffer into which data will output + * + * Converts a standard ATA taskfile to a Serial ATA + * FIS structure (Register - Host to Device). + * + * LOCKING: + * Inherited from caller. + */ +void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) +{ + fis[0] = 0x27; /* Register - Host to Device FIS */ + fis[1] = pmp & 0xf; /* Port multiplier number*/ + if (is_cmd) + fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ + + fis[2] = tf->command; + fis[3] = tf->feature; + + fis[4] = tf->lbal; + fis[5] = tf->lbam; + fis[6] = tf->lbah; + fis[7] = tf->device; + + fis[8] = tf->hob_lbal; + fis[9] = tf->hob_lbam; + fis[10] = tf->hob_lbah; + fis[11] = tf->hob_feature; + + fis[12] = tf->nsect; + fis[13] = tf->hob_nsect; + fis[14] = 0; + fis[15] = tf->ctl; + + fis[16] = tf->auxiliary & 0xff; + fis[17] = (tf->auxiliary >> 8) & 0xff; + fis[18] = (tf->auxiliary >> 16) & 0xff; + fis[19] = (tf->auxiliary >> 24) & 0xff; +} +EXPORT_SYMBOL_GPL(ata_tf_to_fis); + +/** + * ata_tf_from_fis - Convert SATA FIS to ATA taskfile + * @fis: Buffer from which data will be input + * @tf: Taskfile to output + * + * Converts a serial ATA FIS structure to a standard ATA taskfile. + * + * LOCKING: + * Inherited from caller. + */ + +void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) +{ + tf->command = fis[2]; /* status */ + tf->feature = fis[3]; /* error */ + + tf->lbal = fis[4]; + tf->lbam = fis[5]; + tf->lbah = fis[6]; + tf->device = fis[7]; + + tf->hob_lbal = fis[8]; + tf->hob_lbam = fis[9]; + tf->hob_lbah = fis[10]; + + tf->nsect = fis[12]; + tf->hob_nsect = fis[13]; +} +EXPORT_SYMBOL_GPL(ata_tf_from_fis); + +/** + * sata_link_scr_lpm - manipulate SControl IPM and SPM fields + * @link: ATA link to manipulate SControl for + * @policy: LPM policy to configure + * @spm_wakeup: initiate LPM transition to active state + * + * Manipulate the IPM field of the SControl register of @link + * according to @policy. If @policy is ATA_LPM_MAX_POWER and + * @spm_wakeup is %true, the SPM field is manipulated to wake up + * the link. This function also clears PHYRDY_CHG before + * returning. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, + bool spm_wakeup) +{ + struct ata_eh_context *ehc = &link->eh_context; + bool woken_up = false; + u32 scontrol; + int rc; + + rc = sata_scr_read(link, SCR_CONTROL, &scontrol); + if (rc) + return rc; + + switch (policy) { + case ATA_LPM_MAX_POWER: + /* disable all LPM transitions */ + scontrol |= (0x7 << 8); + /* initiate transition to active state */ + if (spm_wakeup) { + scontrol |= (0x4 << 12); + woken_up = true; + } + break; + case ATA_LPM_MED_POWER: + /* allow LPM to PARTIAL */ + scontrol &= ~(0x1 << 8); + scontrol |= (0x6 << 8); + break; + case ATA_LPM_MED_POWER_WITH_DIPM: + case ATA_LPM_MIN_POWER_WITH_PARTIAL: + case ATA_LPM_MIN_POWER: + if (ata_link_nr_enabled(link) > 0) + /* no restrictions on LPM transitions */ + scontrol &= ~(0x7 << 8); + else { + /* empty port, power off */ + scontrol &= ~0xf; + scontrol |= (0x1 << 2); + } + break; + default: + WARN_ON(1); + } + + rc = sata_scr_write(link, SCR_CONTROL, scontrol); + if (rc) + return rc; + + /* give the link time to transit out of LPM state */ + if (woken_up) + msleep(10); + + /* clear PHYRDY_CHG from SError */ + ehc->i.serror &= ~SERR_PHYRDY_CHG; + return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); +} +EXPORT_SYMBOL_GPL(sata_link_scr_lpm); + +/** + * ata_slave_link_init - initialize slave link + * @ap: port to initialize slave link for + * + * Create and initialize slave link for @ap. This enables slave + * link handling on the port. + * + * In libata, a port contains links and a link contains devices. + * There is single host link but if a PMP is attached to it, + * there can be multiple fan-out links. On SATA, there's usually + * a single device connected to a link but PATA and SATA + * controllers emulating TF based interface can have two - master + * and slave. + * + * However, there are a few controllers which don't fit into this + * abstraction too well - SATA controllers which emulate TF + * interface with both master and slave devices but also have + * separate SCR register sets for each device. These controllers + * need separate links for physical link handling + * (e.g. onlineness, link speed) but should be treated like a + * traditional M/S controller for everything else (e.g. command + * issue, softreset). + * + * slave_link is libata's way of handling this class of + * controllers without impacting core layer too much. For + * anything other than physical link handling, the default host + * link is used for both master and slave. For physical link + * handling, separate @ap->slave_link is used. All dirty details + * are implemented inside libata core layer. From LLD's POV, the + * only difference is that prereset, hardreset and postreset are + * called once more for the slave link, so the reset sequence + * looks like the following. + * + * prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> + * softreset(M) -> postreset(M) -> postreset(S) + * + * Note that softreset is called only for the master. Softreset + * resets both M/S by definition, so SRST on master should handle + * both (the standard method will work just fine). + * + * LOCKING: + * Should be called before host is registered. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_slave_link_init(struct ata_port *ap) +{ + struct ata_link *link; + + WARN_ON(ap->slave_link); + WARN_ON(ap->flags & ATA_FLAG_PMP); + + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (!link) + return -ENOMEM; + + ata_link_init(ap, link, 1); + ap->slave_link = link; + return 0; +} +EXPORT_SYMBOL_GPL(ata_slave_link_init); + +/** + * sata_lpm_ignore_phy_events - test if PHY event should be ignored + * @link: Link receiving the event + * + * Test whether the received PHY event has to be ignored or not. + * + * LOCKING: + * None: + * + * RETURNS: + * True if the event has to be ignored. + */ +bool sata_lpm_ignore_phy_events(struct ata_link *link) +{ + unsigned long lpm_timeout = link->last_lpm_change + + msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); + + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (link->lpm_policy > ATA_LPM_MAX_POWER) + return true; + + /* ignore the first PHY event after the LPM policy changed + * as it is might be spurious + */ + if ((link->flags & ATA_LFLAG_CHANGED) && + time_before(jiffies, lpm_timeout)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 408dee580f24..24b8ee668e6f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -531,81 +531,6 @@ int atapi_cmd_type(u8 opcode) } EXPORT_SYMBOL_GPL(atapi_cmd_type); -/** - * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure - * @tf: Taskfile to convert - * @pmp: Port multiplier port - * @is_cmd: This FIS is for command - * @fis: Buffer into which data will output - * - * Converts a standard ATA taskfile to a Serial ATA - * FIS structure (Register - Host to Device). - * - * LOCKING: - * Inherited from caller. - */ -void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) -{ - fis[0] = 0x27; /* Register - Host to Device FIS */ - fis[1] = pmp & 0xf; /* Port multiplier number*/ - if (is_cmd) - fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ - - fis[2] = tf->command; - fis[3] = tf->feature; - - fis[4] = tf->lbal; - fis[5] = tf->lbam; - fis[6] = tf->lbah; - fis[7] = tf->device; - - fis[8] = tf->hob_lbal; - fis[9] = tf->hob_lbam; - fis[10] = tf->hob_lbah; - fis[11] = tf->hob_feature; - - fis[12] = tf->nsect; - fis[13] = tf->hob_nsect; - fis[14] = 0; - fis[15] = tf->ctl; - - fis[16] = tf->auxiliary & 0xff; - fis[17] = (tf->auxiliary >> 8) & 0xff; - fis[18] = (tf->auxiliary >> 16) & 0xff; - fis[19] = (tf->auxiliary >> 24) & 0xff; -} -EXPORT_SYMBOL_GPL(ata_tf_to_fis); - -/** - * ata_tf_from_fis - Convert SATA FIS to ATA taskfile - * @fis: Buffer from which data will be input - * @tf: Taskfile to output - * - * Converts a serial ATA FIS structure to a standard ATA taskfile. - * - * LOCKING: - * Inherited from caller. - */ - -void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) -{ - tf->command = fis[2]; /* status */ - tf->feature = fis[3]; /* error */ - - tf->lbal = fis[4]; - tf->lbam = fis[5]; - tf->lbah = fis[6]; - tf->device = fis[7]; - - tf->hob_lbal = fis[8]; - tf->hob_lbam = fis[9]; - tf->hob_lbah = fis[10]; - - tf->nsect = fis[12]; - tf->hob_nsect = fis[13]; -} -EXPORT_SYMBOL_GPL(ata_tf_from_fis); - static const u8 ata_rw_cmds[] = { /* pio multi */ ATA_CMD_READ_MULTI, @@ -3777,81 +3702,6 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, } EXPORT_SYMBOL_GPL(sata_link_resume); -/** - * sata_link_scr_lpm - manipulate SControl IPM and SPM fields - * @link: ATA link to manipulate SControl for - * @policy: LPM policy to configure - * @spm_wakeup: initiate LPM transition to active state - * - * Manipulate the IPM field of the SControl register of @link - * according to @policy. If @policy is ATA_LPM_MAX_POWER and - * @spm_wakeup is %true, the SPM field is manipulated to wake up - * the link. This function also clears PHYRDY_CHG before - * returning. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, - bool spm_wakeup) -{ - struct ata_eh_context *ehc = &link->eh_context; - bool woken_up = false; - u32 scontrol; - int rc; - - rc = sata_scr_read(link, SCR_CONTROL, &scontrol); - if (rc) - return rc; - - switch (policy) { - case ATA_LPM_MAX_POWER: - /* disable all LPM transitions */ - scontrol |= (0x7 << 8); - /* initiate transition to active state */ - if (spm_wakeup) { - scontrol |= (0x4 << 12); - woken_up = true; - } - break; - case ATA_LPM_MED_POWER: - /* allow LPM to PARTIAL */ - scontrol &= ~(0x1 << 8); - scontrol |= (0x6 << 8); - break; - case ATA_LPM_MED_POWER_WITH_DIPM: - case ATA_LPM_MIN_POWER_WITH_PARTIAL: - case ATA_LPM_MIN_POWER: - if (ata_link_nr_enabled(link) > 0) - /* no restrictions on LPM transitions */ - scontrol &= ~(0x7 << 8); - else { - /* empty port, power off */ - scontrol &= ~0xf; - scontrol |= (0x1 << 2); - } - break; - default: - WARN_ON(1); - } - - rc = sata_scr_write(link, SCR_CONTROL, scontrol); - if (rc) - return rc; - - /* give the link time to transit out of LPM state */ - if (woken_up) - msleep(10); - - /* clear PHYRDY_CHG from SError */ - ehc->i.serror &= ~SERR_PHYRDY_CHG; - return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); -} -EXPORT_SYMBOL_GPL(sata_link_scr_lpm); - /** * ata_std_prereset - prepare for reset * @link: ATA link to be reset @@ -6116,69 +5966,6 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, } EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); -/** - * ata_slave_link_init - initialize slave link - * @ap: port to initialize slave link for - * - * Create and initialize slave link for @ap. This enables slave - * link handling on the port. - * - * In libata, a port contains links and a link contains devices. - * There is single host link but if a PMP is attached to it, - * there can be multiple fan-out links. On SATA, there's usually - * a single device connected to a link but PATA and SATA - * controllers emulating TF based interface can have two - master - * and slave. - * - * However, there are a few controllers which don't fit into this - * abstraction too well - SATA controllers which emulate TF - * interface with both master and slave devices but also have - * separate SCR register sets for each device. These controllers - * need separate links for physical link handling - * (e.g. onlineness, link speed) but should be treated like a - * traditional M/S controller for everything else (e.g. command - * issue, softreset). - * - * slave_link is libata's way of handling this class of - * controllers without impacting core layer too much. For - * anything other than physical link handling, the default host - * link is used for both master and slave. For physical link - * handling, separate @ap->slave_link is used. All dirty details - * are implemented inside libata core layer. From LLD's POV, the - * only difference is that prereset, hardreset and postreset are - * called once more for the slave link, so the reset sequence - * looks like the following. - * - * prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> - * softreset(M) -> postreset(M) -> postreset(S) - * - * Note that softreset is called only for the master. Softreset - * resets both M/S by definition, so SRST on master should handle - * both (the standard method will work just fine). - * - * LOCKING: - * Should be called before host is registered. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int ata_slave_link_init(struct ata_port *ap) -{ - struct ata_link *link; - - WARN_ON(ap->slave_link); - WARN_ON(ap->flags & ATA_FLAG_PMP); - - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) - return -ENOMEM; - - ata_link_init(ap, link, 1); - ap->slave_link = link; - return 0; -} -EXPORT_SYMBOL_GPL(ata_slave_link_init); - static void ata_host_stop(struct device *gendev, void *res) { struct ata_host *host = dev_get_drvdata(gendev); @@ -7083,38 +6870,6 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, } EXPORT_SYMBOL_GPL(ata_wait_register); -/** - * sata_lpm_ignore_phy_events - test if PHY event should be ignored - * @link: Link receiving the event - * - * Test whether the received PHY event has to be ignored or not. - * - * LOCKING: - * None: - * - * RETURNS: - * True if the event has to be ignored. - */ -bool sata_lpm_ignore_phy_events(struct ata_link *link) -{ - unsigned long lpm_timeout = link->last_lpm_change + - msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); - - /* if LPM is enabled, PHYRDY doesn't mean anything */ - if (link->lpm_policy > ATA_LPM_MAX_POWER) - return true; - - /* ignore the first PHY event after the LPM policy changed - * as it is might be spurious - */ - if ((link->flags & ATA_LFLAG_CHANGED) && - time_before(jiffies, lpm_timeout)) - return true; - - return false; -} -EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); - /* * Dummy port_ops */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 5b7bed18f56e..6bb0bd644f17 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1084,8 +1084,6 @@ extern int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline); extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); -extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, - bool spm_wakeup); extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); @@ -1096,7 +1094,6 @@ extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports); extern struct ata_host *ata_host_alloc_pinfo(struct device *dev, const struct ata_port_info * const * ppi, int n_ports); -extern int ata_slave_link_init(struct ata_port *ap); extern void ata_host_get(struct ata_host *host); extern void ata_host_put(struct ata_host *host); extern int ata_host_start(struct ata_host *host); @@ -1154,9 +1151,6 @@ extern void ata_msleep(struct ata_port *ap, unsigned int msecs); extern u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, unsigned long interval, unsigned long timeout); extern int atapi_cmd_type(u8 opcode); -extern void ata_tf_to_fis(const struct ata_taskfile *tf, - u8 pmp, int is_cmd, u8 *fis); -extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern unsigned long ata_pack_xfermask(unsigned long pio_mask, unsigned long mwdma_mask, unsigned long udma_mask); extern void ata_unpack_xfermask(unsigned long xfer_mask, @@ -1197,7 +1191,19 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q); + +/* + * Core layer (SATA specific part) - drivers/ata/libata-core-sata.c + */ +#ifdef CONFIG_SATA_HOST +extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, + bool spm_wakeup); +extern int ata_slave_link_init(struct ata_port *ap); +extern void ata_tf_to_fis(const struct ata_taskfile *tf, + u8 pmp, int is_cmd, u8 *fis); +extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); +#endif extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 12/28] ata: start separating SATA specific code from libata-core.c 2020-01-28 13:33 ` [PATCH 12/28] ata: start separating SATA specific code from libata-core.c Bartlomiej Zolnierkiewicz @ 2020-01-29 17:26 ` Christoph Hellwig 2020-02-07 14:22 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:26 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:27PM +0100, Bartlomiej Zolnierkiewicz wrote: > Start separating SATA specific code from libata-core.c: > > * move following functions to libata-core-sata.c: Why not call this libata-sata.c? If it is SATA specific it can't be that core :) > + * libata-core-sata.c - SATA specific part of ATA helper library No need for file names in top of file headers. > +/* > + * Core layer (SATA specific part) - drivers/ata/libata-core-sata.c > + */ > +#ifdef CONFIG_SATA_HOST > +extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, > + bool spm_wakeup); > +extern int ata_slave_link_init(struct ata_port *ap); > +extern void ata_tf_to_fis(const struct ata_taskfile *tf, > + u8 pmp, int is_cmd, u8 *fis); > +extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); > extern bool sata_lpm_ignore_phy_events(struct ata_link *link); > +#endif No need for the ifdef. ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 12/28] ata: start separating SATA specific code from libata-core.c 2020-01-29 17:26 ` Christoph Hellwig @ 2020-02-07 14:22 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:22 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:26 PM, Christoph Hellwig wrote: > On Tue, Jan 28, 2020 at 02:33:27PM +0100, Bartlomiej Zolnierkiewicz wrote: >> Start separating SATA specific code from libata-core.c: >> >> * move following functions to libata-core-sata.c: > > Why not call this libata-sata.c? If it is SATA specific it can't be > that core :) Indeed. :) >> + * libata-core-sata.c - SATA specific part of ATA helper library > > No need for file names in top of file headers. > >> +/* >> + * Core layer (SATA specific part) - drivers/ata/libata-core-sata.c >> + */ >> +#ifdef CONFIG_SATA_HOST >> +extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, >> + bool spm_wakeup); >> +extern int ata_slave_link_init(struct ata_port *ap); >> +extern void ata_tf_to_fis(const struct ata_taskfile *tf, >> + u8 pmp, int is_cmd, u8 *fis); >> +extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); >> extern bool sata_lpm_ignore_phy_events(struct ata_link *link); >> +#endif > > No need for the ifdef. All above issues are fixed in v2. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133415eucas1p258c0d5c313e2ae42a05508b67eec16ef@eucas1p2.samsung.com>]
* [PATCH 13/28] ata: move ata_do_link_spd_horkage() to libata-core-sata.c [not found] ` <CGME20200128133415eucas1p258c0d5c313e2ae42a05508b67eec16ef@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:28 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move ata_do_link_spd_horkage() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 36762 572 40 37374 91fe drivers/ata/libata-core.o after: 36627 572 40 37239 9177 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 33 +++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 33 --------------------------------- drivers/ata/libata.h | 7 +++++++ 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 8b939d2db0a6..fed8009981c0 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -87,6 +87,39 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) } EXPORT_SYMBOL_GPL(ata_tf_from_fis); +int ata_do_link_spd_horkage(struct ata_device *dev) +{ + struct ata_link *plink = ata_dev_phys_link(dev); + u32 target, target_limit; + + if (!sata_scr_valid(plink)) + return 0; + + if (dev->horkage & ATA_HORKAGE_1_5_GBPS) + target = 1; + else + return 0; + + target_limit = (1 << target) - 1; + + /* if already on stricter limit, no need to push further */ + if (plink->sata_spd_limit <= target_limit) + return 0; + + plink->sata_spd_limit = target_limit; + + /* Request another EH round by returning -EAGAIN if link is + * going faster than the target speed. Forward progress is + * guaranteed by setting sata_spd_limit to target_limit above. + */ + if (plink->sata_spd > target) { + ata_dev_info(dev, "applying link speed limit horkage to %s\n", + sata_spd_string(target)); + return -EAGAIN; + } + return 0; +} + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 24b8ee668e6f..52bd81bad484 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2074,39 +2074,6 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) return false; } -static int ata_do_link_spd_horkage(struct ata_device *dev) -{ - struct ata_link *plink = ata_dev_phys_link(dev); - u32 target, target_limit; - - if (!sata_scr_valid(plink)) - return 0; - - if (dev->horkage & ATA_HORKAGE_1_5_GBPS) - target = 1; - else - return 0; - - target_limit = (1 << target) - 1; - - /* if already on stricter limit, no need to push further */ - if (plink->sata_spd_limit <= target_limit) - return 0; - - plink->sata_spd_limit = target_limit; - - /* Request another EH round by returning -EAGAIN if link is - * going faster than the target speed. Forward progress is - * guaranteed by setting sata_spd_limit to target_limit above. - */ - if (plink->sata_spd > target) { - ata_dev_info(dev, "applying link speed limit horkage to %s\n", - sata_spd_string(target)); - return -EAGAIN; - } - return 0; -} - static inline u8 ata_dev_knobble(struct ata_device *dev) { struct ata_port *ap = dev->link->ap; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index cd8090ad43e5..9eebe4e0be39 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -87,6 +87,13 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, #define to_ata_port(d) container_of(d, struct ata_port, tdev) +/* libata-core-sata.c */ +#ifdef CONFIG_SATA_HOST +int ata_do_link_spd_horkage(struct ata_device *dev); +#else +static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } +#endif + /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 13/28] ata: move ata_do_link_spd_horkage() to libata-core-sata.c 2020-01-28 13:33 ` [PATCH 13/28] ata: move ata_do_link_spd_horkage() to libata-core-sata.c Bartlomiej Zolnierkiewicz @ 2020-01-29 17:28 ` Christoph Hellwig 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:28 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:28PM +0100, Bartlomiej Zolnierkiewicz wrote: > * move ata_do_link_spd_horkage() to libata-core-sata.c > > * add static inline for CONFIG_SATA_HOST=n case Wouldn't it make more sense to stub out sata_scr_valid for the !SATA case and just let the compiler optimize the function away now that it can't be called in that case? ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 13/28] ata: move ata_do_link_spd_horkage() to libata-core-sata.c 2020-01-29 17:28 ` Christoph Hellwig @ 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:23 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:28 PM, Christoph Hellwig wrote: > On Tue, Jan 28, 2020 at 02:33:28PM +0100, Bartlomiej Zolnierkiewicz wrote: >> * move ata_do_link_spd_horkage() to libata-core-sata.c >> >> * add static inline for CONFIG_SATA_HOST=n case > > Wouldn't it make more sense to stub out sata_scr_valid for the !SATA > case and just let the compiler optimize the function away now that it > can't be called in that case? I've reworked the code to use this approach in v2 of the patchset. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133415eucas1p1cd35ec3ee9783b76c1a32de63796ce30@eucas1p1.samsung.com>]
* [PATCH 14/28] ata: move ata_dev_config_ncq*() to libata-core-sata.c [not found] ` <CGME20200128133415eucas1p1cd35ec3ee9783b76c1a32de63796ce30@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:29 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move ata_log_supported() to libata.h and make it inline * move ata_dev_config_ncq*() to libata-core-sata.c * add static inline version of ata_dev_config_ncq() for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 36627 572 40 37239 9177 drivers/ata/libata-core.o after: 35499 572 40 36111 8d0f drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 138 ++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 148 --------------------------------- drivers/ata/libata.h | 18 ++++ 3 files changed, 156 insertions(+), 148 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index fed8009981c0..f2629e069a55 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -120,6 +120,144 @@ int ata_do_link_spd_horkage(struct ata_device *dev) return 0; } +static void ata_dev_config_ncq_send_recv(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { + ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); + return; + } + err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, + 0, ap->sector_buf, 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get NCQ Send/Recv Log Emask 0x%x\n", + err_mask); + } else { + u8 *cmds = dev->ncq_send_recv_cmds; + + dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; + memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); + + if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) { + ata_dev_dbg(dev, "disabling queued TRIM support\n"); + cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &= + ~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM; + } + } +} + +static void ata_dev_config_ncq_non_data(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { + ata_dev_warn(dev, + "NCQ Send/Recv Log not supported\n"); + return; + } + err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, + 0, ap->sector_buf, 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get NCQ Non-Data Log Emask 0x%x\n", + err_mask); + } else { + u8 *cmds = dev->ncq_non_data_cmds; + + memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); + } +} + +static void ata_dev_config_ncq_prio(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO; + return; + } + + err_mask = ata_read_log_page(dev, + ATA_LOG_IDENTIFY_DEVICE, + ATA_LOG_SATA_SETTINGS, + ap->sector_buf, + 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get Identify Device data, Emask 0x%x\n", + err_mask); + return; + } + + if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) { + dev->flags |= ATA_DFLAG_NCQ_PRIO; + } else { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO; + ata_dev_dbg(dev, "SATA page does not support priority\n"); + } + +} + +int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz) +{ + struct ata_port *ap = dev->link->ap; + int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); + unsigned int err_mask; + char *aa_desc = ""; + + if (!ata_id_has_ncq(dev->id)) { + desc[0] = '\0'; + return 0; + } + if (dev->horkage & ATA_HORKAGE_NONCQ) { + snprintf(desc, desc_sz, "NCQ (not used)"); + return 0; + } + if (ap->flags & ATA_FLAG_NCQ) { + hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE); + dev->flags |= ATA_DFLAG_NCQ; + } + + if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) && + (ap->flags & ATA_FLAG_FPDMA_AA) && + ata_id_has_fpdma_aa(dev->id)) { + err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, + SATA_FPDMA_AA); + if (err_mask) { + ata_dev_err(dev, + "failed to enable AA (error_mask=0x%x)\n", + err_mask); + if (err_mask != AC_ERR_DEV) { + dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA; + return -EIO; + } + } else + aa_desc = ", AA"; + } + + if (hdepth >= ddepth) + snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc); + else + snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, + ddepth, aa_desc); + + if ((ap->flags & ATA_FLAG_FPDMA_AUX)) { + if (ata_id_has_ncq_send_and_recv(dev->id)) + ata_dev_config_ncq_send_recv(dev); + if (ata_id_has_ncq_non_data(dev->id)) + ata_dev_config_ncq_non_data(dev); + if (ata_id_has_ncq_prio(dev->id)) + ata_dev_config_ncq_prio(dev); + } + + return 0; +} + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 52bd81bad484..0a90e0e65f0b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2034,15 +2034,6 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, return err_mask; } -static bool ata_log_supported(struct ata_device *dev, u8 log) -{ - struct ata_port *ap = dev->link->ap; - - if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) - return false; - return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; -} - static bool ata_identify_page_supported(struct ata_device *dev, u8 page) { struct ata_port *ap = dev->link->ap; @@ -2084,145 +2075,6 @@ static inline u8 ata_dev_knobble(struct ata_device *dev) return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); } -static void ata_dev_config_ncq_send_recv(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { - ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); - return; - } - err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, - 0, ap->sector_buf, 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get NCQ Send/Recv Log Emask 0x%x\n", - err_mask); - } else { - u8 *cmds = dev->ncq_send_recv_cmds; - - dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); - - if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) { - ata_dev_dbg(dev, "disabling queued TRIM support\n"); - cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &= - ~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM; - } - } -} - -static void ata_dev_config_ncq_non_data(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { - ata_dev_warn(dev, - "NCQ Send/Recv Log not supported\n"); - return; - } - err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, - 0, ap->sector_buf, 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get NCQ Non-Data Log Emask 0x%x\n", - err_mask); - } else { - u8 *cmds = dev->ncq_non_data_cmds; - - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); - } -} - -static void ata_dev_config_ncq_prio(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO; - return; - } - - err_mask = ata_read_log_page(dev, - ATA_LOG_IDENTIFY_DEVICE, - ATA_LOG_SATA_SETTINGS, - ap->sector_buf, - 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get Identify Device data, Emask 0x%x\n", - err_mask); - return; - } - - if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) { - dev->flags |= ATA_DFLAG_NCQ_PRIO; - } else { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO; - ata_dev_dbg(dev, "SATA page does not support priority\n"); - } - -} - -static int ata_dev_config_ncq(struct ata_device *dev, - char *desc, size_t desc_sz) -{ - struct ata_port *ap = dev->link->ap; - int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); - unsigned int err_mask; - char *aa_desc = ""; - - if (!ata_id_has_ncq(dev->id)) { - desc[0] = '\0'; - return 0; - } - if (dev->horkage & ATA_HORKAGE_NONCQ) { - snprintf(desc, desc_sz, "NCQ (not used)"); - return 0; - } - if (ap->flags & ATA_FLAG_NCQ) { - hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE); - dev->flags |= ATA_DFLAG_NCQ; - } - - if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) && - (ap->flags & ATA_FLAG_FPDMA_AA) && - ata_id_has_fpdma_aa(dev->id)) { - err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, - SATA_FPDMA_AA); - if (err_mask) { - ata_dev_err(dev, - "failed to enable AA (error_mask=0x%x)\n", - err_mask); - if (err_mask != AC_ERR_DEV) { - dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA; - return -EIO; - } - } else - aa_desc = ", AA"; - } - - if (hdepth >= ddepth) - snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc); - else - snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, - ddepth, aa_desc); - - if ((ap->flags & ATA_FLAG_FPDMA_AUX)) { - if (ata_id_has_ncq_send_and_recv(dev->id)) - ata_dev_config_ncq_send_recv(dev); - if (ata_id_has_ncq_non_data(dev->id)) - ata_dev_config_ncq_non_data(dev); - if (ata_id_has_ncq_prio(dev->id)) - ata_dev_config_ncq_prio(dev); - } - - return 0; -} - static void ata_dev_config_sense_reporting(struct ata_device *dev) { unsigned int err_mask; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 9eebe4e0be39..24b08efd79a3 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -15,6 +15,8 @@ #define DRV_NAME "libata" #define DRV_VERSION "3.00" /* must be exactly four chars */ +#include <asm/unaligned.h> + /* libata-core.c */ enum { /* flags for ata_dev_read_id() */ @@ -85,13 +87,29 @@ extern void __ata_port_probe(struct ata_port *ap); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); +static inline bool ata_log_supported(struct ata_device *dev, u8 log) +{ + struct ata_port *ap = dev->link->ap; + + if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) + return false; + return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; +} + #define to_ata_port(d) container_of(d, struct ata_port, tdev) /* libata-core-sata.c */ #ifdef CONFIG_SATA_HOST int ata_do_link_spd_horkage(struct ata_device *dev); +int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } +static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, + size_t desc_sz) +{ + desc[0] = '\0'; + return 0; +} #endif /* libata-acpi.c */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 14/28] ata: move ata_dev_config_ncq*() to libata-core-sata.c 2020-01-28 13:33 ` [PATCH 14/28] ata: move ata_dev_config_ncq*() " Bartlomiej Zolnierkiewicz @ 2020-01-29 17:29 ` Christoph Hellwig 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:29 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:29PM +0100, Bartlomiej Zolnierkiewicz wrote: > * move ata_log_supported() to libata.h and make it inline > > * move ata_dev_config_ncq*() to libata-core-sata.c > > * add static inline version of ata_dev_config_ncq() for > CONFIG_SATA_HOST=n case Wouldn't it be easier to throw in an IS_ENABLED() into the ATA_FLAG_FPDMA_AUX before calling ata_dev_config_ncq_* and let the compiler optimize out the functions? ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 14/28] ata: move ata_dev_config_ncq*() to libata-core-sata.c 2020-01-29 17:29 ` Christoph Hellwig @ 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:23 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:29 PM, Christoph Hellwig wrote: > On Tue, Jan 28, 2020 at 02:33:29PM +0100, Bartlomiej Zolnierkiewicz wrote: >> * move ata_log_supported() to libata.h and make it inline >> >> * move ata_dev_config_ncq*() to libata-core-sata.c >> >> * add static inline version of ata_dev_config_ncq() for >> CONFIG_SATA_HOST=n case > > Wouldn't it be easier to throw in an IS_ENABLED() into the > ATA_FLAG_FPDMA_AUX before calling ata_dev_config_ncq_* and let the > compiler optimize out the functions? I've reworked the code to use this approach in v2 of the patchset. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133415eucas1p12cc620dd5f19e6a26f1deeba083ea82f@eucas1p1.samsung.com>]
* [PATCH 15/28] ata: move sata_print_link_status() to libata-core-sata.c [not found] ` <CGME20200128133415eucas1p12cc620dd5f19e6a26f1deeba083ea82f@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:30 ` Christoph Hellwig 0 siblings, 1 reply; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_print_link_status() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 35499 572 40 36111 8d0f drivers/ata/libata-core.o after: 35276 572 40 35888 8c30 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 27 +++++++++++++++++++++++++++ drivers/ata/libata-core.c | 27 --------------------------- drivers/ata/libata.h | 2 ++ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index f2629e069a55..8ad8f97660df 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -258,6 +258,33 @@ int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz) return 0; } +/** + * sata_print_link_status - Print SATA link status + * @link: SATA link to printk link status about + * + * This function prints link speed and status of a SATA link. + * + * LOCKING: + * None. + */ +void sata_print_link_status(struct ata_link *link) +{ + u32 sstatus, scontrol, tmp; + + if (sata_scr_read(link, SCR_STATUS, &sstatus)) + return; + sata_scr_read(link, SCR_CONTROL, &scontrol); + + if (ata_phys_link_online(link)) { + tmp = (sstatus >> 4) & 0xf; + ata_link_info(link, "SATA link up %s (SStatus %X SControl %X)\n", + sata_spd_string(tmp), sstatus, scontrol); + } else { + ata_link_info(link, "SATA link down (SStatus %X SControl %X)\n", + sstatus, scontrol); + } +} + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0a90e0e65f0b..73f732a32261 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2742,33 +2742,6 @@ int ata_bus_probe(struct ata_port *ap) goto retry; } -/** - * sata_print_link_status - Print SATA link status - * @link: SATA link to printk link status about - * - * This function prints link speed and status of a SATA link. - * - * LOCKING: - * None. - */ -static void sata_print_link_status(struct ata_link *link) -{ - u32 sstatus, scontrol, tmp; - - if (sata_scr_read(link, SCR_STATUS, &sstatus)) - return; - sata_scr_read(link, SCR_CONTROL, &scontrol); - - if (ata_phys_link_online(link)) { - tmp = (sstatus >> 4) & 0xf; - ata_link_info(link, "SATA link up %s (SStatus %X SControl %X)\n", - sata_spd_string(tmp), sstatus, scontrol); - } else { - ata_link_info(link, "SATA link down (SStatus %X SControl %X)\n", - sstatus, scontrol); - } -} - /** * ata_dev_pair - return other device on cable * @adev: device diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 24b08efd79a3..909c2cae52a0 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -102,6 +102,7 @@ static inline bool ata_log_supported(struct ata_device *dev, u8 log) #ifdef CONFIG_SATA_HOST int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); +void sata_print_link_status(struct ata_link *link); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -110,6 +111,7 @@ static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, desc[0] = '\0'; return 0; } +static inline void sata_print_link_status(struct ata_link *link) { } #endif /* libata-acpi.c */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 15/28] ata: move sata_print_link_status() to libata-core-sata.c 2020-01-28 13:33 ` [PATCH 15/28] ata: move sata_print_link_status() " Bartlomiej Zolnierkiewicz @ 2020-01-29 17:30 ` Christoph Hellwig 2020-02-07 14:24 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:30 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:30PM +0100, Bartlomiej Zolnierkiewicz wrote: > * move sata_print_link_status() to libata-core-sata.c > > * add static inline for CONFIG_SATA_HOST=n case With the IS_ENABLED() in sata_scr_read the compile should be able to just do this by itself - maybe with an inline thrown in for sata_print_link_status if the compiler behaves stupidly. ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 15/28] ata: move sata_print_link_status() to libata-core-sata.c 2020-01-29 17:30 ` Christoph Hellwig @ 2020-02-07 14:24 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:24 UTC (permalink / raw) To: Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:30 PM, Christoph Hellwig wrote: > On Tue, Jan 28, 2020 at 02:33:30PM +0100, Bartlomiej Zolnierkiewicz wrote: >> * move sata_print_link_status() to libata-core-sata.c >> >> * add static inline for CONFIG_SATA_HOST=n case > > With the IS_ENABLED() in sata_scr_read the compile should be able to > just do this by itself - maybe with an inline thrown in for > sata_print_link_status if the compiler behaves stupidly. I've reworked the code to use this approach in v2 of the patchset. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133416eucas1p1eb121384be2323aed1fc63a6d1ebe14f@eucas1p1.samsung.com>]
* [PATCH 16/28] ata: move sata_down_spd_limit() to libata-core-sata.c [not found] ` <CGME20200128133416eucas1p1eb121384be2323aed1fc63a6d1ebe14f@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move ata_sstatus_online() to libata.h and make it inline * move sata_down_spd_limit() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 35276 572 40 35888 8c30 drivers/ata/libata-core.o after: 34996 572 40 35608 8b18 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 80 ++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 85 ---------------------------------- drivers/ata/libata.h | 11 ++++- 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 8ad8f97660df..fb956c8aee9a 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -285,6 +285,86 @@ void sata_print_link_status(struct ata_link *link) } } +/** + * sata_down_spd_limit - adjust SATA spd limit downward + * @link: Link to adjust SATA spd limit for + * @spd_limit: Additional limit + * + * Adjust SATA spd limit of @link downward. Note that this + * function only adjusts the limit. The change must be applied + * using sata_set_spd(). + * + * If @spd_limit is non-zero, the speed is limited to equal to or + * lower than @spd_limit if such speed is supported. If + * @spd_limit is slower than any supported speed, only the lowest + * supported speed is allowed. + * + * LOCKING: + * Inherited from caller. + * + * RETURNS: + * 0 on success, negative errno on failure + */ +int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +{ + u32 sstatus, spd, mask; + int rc, bit; + + if (!sata_scr_valid(link)) + return -EOPNOTSUPP; + + /* If SCR can be read, use it to determine the current SPD. + * If not, use cached value in link->sata_spd. + */ + rc = sata_scr_read(link, SCR_STATUS, &sstatus); + if (rc == 0 && ata_sstatus_online(sstatus)) + spd = (sstatus >> 4) & 0xf; + else + spd = link->sata_spd; + + mask = link->sata_spd_limit; + if (mask <= 1) + return -EINVAL; + + /* unconditionally mask off the highest bit */ + bit = fls(mask) - 1; + mask &= ~(1 << bit); + + /* + * Mask off all speeds higher than or equal to the current one. At + * this point, if current SPD is not available and we previously + * recorded the link speed from SStatus, the driver has already + * masked off the highest bit so mask should already be 1 or 0. + * Otherwise, we should not force 1.5Gbps on a link where we have + * not previously recorded speed from SStatus. Just return in this + * case. + */ + if (spd > 1) + mask &= (1 << (spd - 1)) - 1; + else + return -EINVAL; + + /* were we already at the bottom? */ + if (!mask) + return -EINVAL; + + if (spd_limit) { + if (mask & ((1 << spd_limit) - 1)) + mask &= (1 << spd_limit) - 1; + else { + bit = ffs(mask) - 1; + mask = 1 << bit; + } + } + + link->sata_spd_limit = mask; + + ata_link_warn(link, "limiting SATA link speed to %s\n", + sata_spd_string(fls(mask))); + + return 0; +} + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 73f732a32261..1d0744f18754 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -167,11 +167,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -static bool ata_sstatus_online(u32 sstatus) -{ - return (sstatus & 0xf) == 0x3; -} - /** * ata_link_next - link iteration helper * @link: the previous link, NULL to start @@ -2760,86 +2755,6 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) } EXPORT_SYMBOL_GPL(ata_dev_pair); -/** - * sata_down_spd_limit - adjust SATA spd limit downward - * @link: Link to adjust SATA spd limit for - * @spd_limit: Additional limit - * - * Adjust SATA spd limit of @link downward. Note that this - * function only adjusts the limit. The change must be applied - * using sata_set_spd(). - * - * If @spd_limit is non-zero, the speed is limited to equal to or - * lower than @spd_limit if such speed is supported. If - * @spd_limit is slower than any supported speed, only the lowest - * supported speed is allowed. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 on success, negative errno on failure - */ -int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) -{ - u32 sstatus, spd, mask; - int rc, bit; - - if (!sata_scr_valid(link)) - return -EOPNOTSUPP; - - /* If SCR can be read, use it to determine the current SPD. - * If not, use cached value in link->sata_spd. - */ - rc = sata_scr_read(link, SCR_STATUS, &sstatus); - if (rc == 0 && ata_sstatus_online(sstatus)) - spd = (sstatus >> 4) & 0xf; - else - spd = link->sata_spd; - - mask = link->sata_spd_limit; - if (mask <= 1) - return -EINVAL; - - /* unconditionally mask off the highest bit */ - bit = fls(mask) - 1; - mask &= ~(1 << bit); - - /* - * Mask off all speeds higher than or equal to the current one. At - * this point, if current SPD is not available and we previously - * recorded the link speed from SStatus, the driver has already - * masked off the highest bit so mask should already be 1 or 0. - * Otherwise, we should not force 1.5Gbps on a link where we have - * not previously recorded speed from SStatus. Just return in this - * case. - */ - if (spd > 1) - mask &= (1 << (spd - 1)) - 1; - else - return -EINVAL; - - /* were we already at the bottom? */ - if (!mask) - return -EINVAL; - - if (spd_limit) { - if (mask & ((1 << spd_limit) - 1)) - mask &= (1 << spd_limit) - 1; - else { - bit = ffs(mask) - 1; - mask = 1 << bit; - } - } - - link->sata_spd_limit = mask; - - ata_link_warn(link, "limiting SATA link speed to %s\n", - sata_spd_string(fls(mask))); - - return 0; -} - static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) { struct ata_link *host_link = &link->ap->link; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 909c2cae52a0..518a8e08a26d 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -64,7 +64,6 @@ 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 int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature); @@ -87,6 +86,11 @@ extern void __ata_port_probe(struct ata_port *ap); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); +static inline bool ata_sstatus_online(u32 sstatus) +{ + return (sstatus & 0xf) == 0x3; +} + static inline bool ata_log_supported(struct ata_device *dev, u8 log) { struct ata_port *ap = dev->link->ap; @@ -103,6 +107,7 @@ static inline bool ata_log_supported(struct ata_device *dev, u8 log) int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); void sata_print_link_status(struct ata_link *link); +int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -112,6 +117,10 @@ static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, return 0; } static inline void sata_print_link_status(struct ata_link *link) { } +static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +{ + return -EOPNOTSUPP; +} #endif /* libata-acpi.c */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133416eucas1p240f8fc15b334e0608cce30f2b6f0fbe1@eucas1p2.samsung.com>]
* [PATCH 17/28] ata: move *sata_set_spd*() to libata-core-sata.c [not found] ` <CGME20200128133416eucas1p240f8fc15b334e0608cce30f2b6f0fbe1@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move *sata_set_spd*() to libata-core-sata.c * add static inlines for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 34996 572 40 35608 8b18 drivers/ata/libata-core.o after: 34766 572 40 35378 8a32 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 81 ++++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 81 ---------------------------------- drivers/ata/libata.h | 2 + include/linux/libata.h | 4 +- 4 files changed, 86 insertions(+), 82 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index fb956c8aee9a..4aa938c1df8d 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -365,6 +365,87 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) return 0; } +static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) +{ + struct ata_link *host_link = &link->ap->link; + u32 limit, target, spd; + + limit = link->sata_spd_limit; + + /* Don't configure downstream link faster than upstream link. + * It doesn't speed up anything and some PMPs choke on such + * configuration. + */ + if (!ata_is_host_link(link) && host_link->sata_spd) + limit &= (1 << host_link->sata_spd) - 1; + + if (limit == UINT_MAX) + target = 0; + else + target = fls(limit); + + spd = (*scontrol >> 4) & 0xf; + *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4); + + return spd != target; +} + +/** + * sata_set_spd_needed - is SATA spd configuration needed + * @link: Link in question + * + * Test whether the spd limit in SControl matches + * @link->sata_spd_limit. This function is used to determine + * whether hardreset is necessary to apply SATA spd + * configuration. + * + * LOCKING: + * Inherited from caller. + * + * RETURNS: + * 1 if SATA spd configuration is needed, 0 otherwise. + */ +int sata_set_spd_needed(struct ata_link *link) +{ + u32 scontrol; + + if (sata_scr_read(link, SCR_CONTROL, &scontrol)) + return 1; + + return __sata_set_spd_needed(link, &scontrol); +} + +/** + * sata_set_spd - set SATA spd according to spd limit + * @link: Link to set SATA spd for + * + * Set SATA spd of @link according to sata_spd_limit. + * + * LOCKING: + * Inherited from caller. + * + * RETURNS: + * 0 if spd doesn't need to be changed, 1 if spd has been + * changed. Negative errno if SCR registers are inaccessible. + */ +int sata_set_spd(struct ata_link *link) +{ + u32 scontrol; + int rc; + + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + return rc; + + if (!__sata_set_spd_needed(link, &scontrol)) + return 0; + + if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) + return rc; + + return 1; +} +EXPORT_SYMBOL_GPL(sata_set_spd); + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1d0744f18754..ff44d16b718e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2755,87 +2755,6 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) } EXPORT_SYMBOL_GPL(ata_dev_pair); -static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) -{ - struct ata_link *host_link = &link->ap->link; - u32 limit, target, spd; - - limit = link->sata_spd_limit; - - /* Don't configure downstream link faster than upstream link. - * It doesn't speed up anything and some PMPs choke on such - * configuration. - */ - if (!ata_is_host_link(link) && host_link->sata_spd) - limit &= (1 << host_link->sata_spd) - 1; - - if (limit == UINT_MAX) - target = 0; - else - target = fls(limit); - - spd = (*scontrol >> 4) & 0xf; - *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4); - - return spd != target; -} - -/** - * sata_set_spd_needed - is SATA spd configuration needed - * @link: Link in question - * - * Test whether the spd limit in SControl matches - * @link->sata_spd_limit. This function is used to determine - * whether hardreset is necessary to apply SATA spd - * configuration. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 1 if SATA spd configuration is needed, 0 otherwise. - */ -static int sata_set_spd_needed(struct ata_link *link) -{ - u32 scontrol; - - if (sata_scr_read(link, SCR_CONTROL, &scontrol)) - return 1; - - return __sata_set_spd_needed(link, &scontrol); -} - -/** - * sata_set_spd - set SATA spd according to spd limit - * @link: Link to set SATA spd for - * - * Set SATA spd of @link according to sata_spd_limit. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 if spd doesn't need to be changed, 1 if spd has been - * changed. Negative errno if SCR registers are inaccessible. - */ -int sata_set_spd(struct ata_link *link) -{ - u32 scontrol; - int rc; - - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - return rc; - - if (!__sata_set_spd_needed(link, &scontrol)) - return 0; - - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - return rc; - - return 1; -} -EXPORT_SYMBOL_GPL(sata_set_spd); - #ifdef CONFIG_ATA_ACPI /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 518a8e08a26d..ea614ac10c76 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -108,6 +108,7 @@ int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); void sata_print_link_status(struct ata_link *link); int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); +int sata_set_spd_needed(struct ata_link *link); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -121,6 +122,7 @@ static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) { return -EOPNOTSUPP; } +static inline int sata_set_spd_needed(struct ata_link *link) { return 1; } #endif /* libata-acpi.c */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 6bb0bd644f17..e466dbe56158 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1076,7 +1076,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) return ap->ops == &ata_dummy_port_ops; } -extern int sata_set_spd(struct ata_link *link); extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); @@ -1196,6 +1195,7 @@ extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port * * Core layer (SATA specific part) - drivers/ata/libata-core-sata.c */ #ifdef CONFIG_SATA_HOST +extern int sata_set_spd(struct ata_link *link); extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup); extern int ata_slave_link_init(struct ata_port *ap); @@ -1203,6 +1203,8 @@ extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); +#else +static inline int sata_set_spd(struct ata_link *link) { return -EOPNOTSUPP; } #endif extern int ata_cable_40wire(struct ata_port *ap); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133416eucas1p172512260c12e8cce9516dd194c467134@eucas1p1.samsung.com>]
* [PATCH 18/28] ata: move sata_link_{debounce,resume}() to libata-core-sata.c [not found] ` <CGME20200128133416eucas1p172512260c12e8cce9516dd194c467134@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_link_{debounce,resume}() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case (only one, for sata_link_resume() is needed) Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 34766 572 40 35378 8a32 drivers/ata/libata-core.o after: 33909 572 40 34521 86d9 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 138 +++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 138 --------------------------------- include/linux/libata.h | 14 +++- 3 files changed, 148 insertions(+), 142 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 4aa938c1df8d..73f8be386a44 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -446,6 +446,144 @@ int sata_set_spd(struct ata_link *link) } EXPORT_SYMBOL_GPL(sata_set_spd); +/** + * sata_link_debounce - debounce SATA phy status + * @link: ATA link to debounce SATA phy status for + * @params: timing parameters { interval, duration, timeout } in msec + * @deadline: deadline jiffies for the operation + * + * Make sure SStatus of @link reaches stable state, determined by + * holding the same value where DET is not 1 for @duration polled + * every @interval, before @timeout. Timeout constraints the + * beginning of the stable state. Because DET gets stuck at 1 on + * some controllers after hot unplugging, this functions waits + * until timeout then returns 0 if DET is stable at 1. + * + * @timeout is further limited by @deadline. The sooner of the + * two is used. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int sata_link_debounce(struct ata_link *link, const unsigned long *params, + unsigned long deadline) +{ + unsigned long interval = params[0]; + unsigned long duration = params[1]; + unsigned long last_jiffies, t; + u32 last, cur; + int rc; + + t = ata_deadline(jiffies, params[2]); + if (time_before(t, deadline)) + deadline = t; + + if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) + return rc; + cur &= 0xf; + + last = cur; + last_jiffies = jiffies; + + while (1) { + ata_msleep(link->ap, interval); + if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) + return rc; + cur &= 0xf; + + /* DET stable? */ + if (cur == last) { + if (cur == 1 && time_before(jiffies, deadline)) + continue; + if (time_after(jiffies, + ata_deadline(last_jiffies, duration))) + return 0; + continue; + } + + /* unstable, start over */ + last = cur; + last_jiffies = jiffies; + + /* Check deadline. If debouncing failed, return + * -EPIPE to tell upper layer to lower link speed. + */ + if (time_after(jiffies, deadline)) + return -EPIPE; + } +} +EXPORT_SYMBOL_GPL(sata_link_debounce); + +/** + * sata_link_resume - resume SATA link + * @link: ATA link to resume SATA + * @params: timing parameters { interval, duration, timeout } in msec + * @deadline: deadline jiffies for the operation + * + * Resume SATA phy @link and debounce it. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int sata_link_resume(struct ata_link *link, const unsigned long *params, + unsigned long deadline) +{ + int tries = ATA_LINK_RESUME_TRIES; + u32 scontrol, serror; + int rc; + + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + return rc; + + /* + * Writes to SControl sometimes get ignored under certain + * controllers (ata_piix SIDPR). Make sure DET actually is + * cleared. + */ + do { + scontrol = (scontrol & 0x0f0) | 0x300; + if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) + return rc; + /* + * Some PHYs react badly if SStatus is pounded + * immediately after resuming. Delay 200ms before + * debouncing. + */ + if (!(link->flags & ATA_LFLAG_NO_DB_DELAY)) + ata_msleep(link->ap, 200); + + /* is SControl restored correctly? */ + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + return rc; + } while ((scontrol & 0xf0f) != 0x300 && --tries); + + if ((scontrol & 0xf0f) != 0x300) { + ata_link_warn(link, "failed to resume link (SControl %X)\n", + scontrol); + return 0; + } + + if (tries < ATA_LINK_RESUME_TRIES) + ata_link_warn(link, "link resume succeeded after %d retries\n", + ATA_LINK_RESUME_TRIES - tries); + + if ((rc = sata_link_debounce(link, params, deadline))) + return rc; + + /* clear SError, some PHYs require this even for SRST to work */ + if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) + rc = sata_scr_write(link, SCR_ERROR, serror); + + return rc != -EINVAL ? rc : 0; +} +EXPORT_SYMBOL_GPL(sata_link_resume); + /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ff44d16b718e..d3587fb1e78c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3190,144 +3190,6 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, } EXPORT_SYMBOL_GPL(ata_wait_after_reset); -/** - * sata_link_debounce - debounce SATA phy status - * @link: ATA link to debounce SATA phy status for - * @params: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * - * Make sure SStatus of @link reaches stable state, determined by - * holding the same value where DET is not 1 for @duration polled - * every @interval, before @timeout. Timeout constraints the - * beginning of the stable state. Because DET gets stuck at 1 on - * some controllers after hot unplugging, this functions waits - * until timeout then returns 0 if DET is stable at 1. - * - * @timeout is further limited by @deadline. The sooner of the - * two is used. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_link_debounce(struct ata_link *link, const unsigned long *params, - unsigned long deadline) -{ - unsigned long interval = params[0]; - unsigned long duration = params[1]; - unsigned long last_jiffies, t; - u32 last, cur; - int rc; - - t = ata_deadline(jiffies, params[2]); - if (time_before(t, deadline)) - deadline = t; - - if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - last = cur; - last_jiffies = jiffies; - - while (1) { - ata_msleep(link->ap, interval); - if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - /* DET stable? */ - if (cur == last) { - if (cur == 1 && time_before(jiffies, deadline)) - continue; - if (time_after(jiffies, - ata_deadline(last_jiffies, duration))) - return 0; - continue; - } - - /* unstable, start over */ - last = cur; - last_jiffies = jiffies; - - /* Check deadline. If debouncing failed, return - * -EPIPE to tell upper layer to lower link speed. - */ - if (time_after(jiffies, deadline)) - return -EPIPE; - } -} -EXPORT_SYMBOL_GPL(sata_link_debounce); - -/** - * sata_link_resume - resume SATA link - * @link: ATA link to resume SATA - * @params: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * - * Resume SATA phy @link and debounce it. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_link_resume(struct ata_link *link, const unsigned long *params, - unsigned long deadline) -{ - int tries = ATA_LINK_RESUME_TRIES; - u32 scontrol, serror; - int rc; - - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - return rc; - - /* - * Writes to SControl sometimes get ignored under certain - * controllers (ata_piix SIDPR). Make sure DET actually is - * cleared. - */ - do { - scontrol = (scontrol & 0x0f0) | 0x300; - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - return rc; - /* - * Some PHYs react badly if SStatus is pounded - * immediately after resuming. Delay 200ms before - * debouncing. - */ - if (!(link->flags & ATA_LFLAG_NO_DB_DELAY)) - ata_msleep(link->ap, 200); - - /* is SControl restored correctly? */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - return rc; - } while ((scontrol & 0xf0f) != 0x300 && --tries); - - if ((scontrol & 0xf0f) != 0x300) { - ata_link_warn(link, "failed to resume link (SControl %X)\n", - scontrol); - return 0; - } - - if (tries < ATA_LINK_RESUME_TRIES) - ata_link_warn(link, "link resume succeeded after %d retries\n", - ATA_LINK_RESUME_TRIES - tries); - - if ((rc = sata_link_debounce(link, params, deadline))) - return rc; - - /* clear SError, some PHYs require this even for SRST to work */ - if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) - rc = sata_scr_write(link, SCR_ERROR, serror); - - return rc != -EINVAL ? rc : 0; -} -EXPORT_SYMBOL_GPL(sata_link_resume); - /** * ata_std_prereset - prepare for reset * @link: ATA link to be reset diff --git a/include/linux/libata.h b/include/linux/libata.h index e466dbe56158..8a11ae3a019f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1079,10 +1079,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); -extern int sata_link_debounce(struct ata_link *link, - const unsigned long *params, unsigned long deadline); -extern int sata_link_resume(struct ata_link *link, const unsigned long *params, - unsigned long deadline); extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); @@ -1196,6 +1192,10 @@ extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port * */ #ifdef CONFIG_SATA_HOST extern int sata_set_spd(struct ata_link *link); +extern int sata_link_debounce(struct ata_link *link, + const unsigned long *params, unsigned long deadline); +extern int sata_link_resume(struct ata_link *link, const unsigned long *params, + unsigned long deadline); extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup); extern int ata_slave_link_init(struct ata_port *ap); @@ -1205,6 +1205,12 @@ extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); #else static inline int sata_set_spd(struct ata_link *link) { return -EOPNOTSUPP; } +static inline int sata_link_resume(struct ata_link *link, + const unsigned long *params, + unsigned long deadline) +{ + return -EOPNOTSUPP; +} #endif extern int ata_cable_40wire(struct ata_port *ap); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133417eucas1p1b907d220ad2b809cdf628fb47a14589c@eucas1p1.samsung.com>]
* [PATCH 19/28] ata: move sata_link_hardreset() to libata-core-sata.c [not found] ` <CGME20200128133417eucas1p1b907d220ad2b809cdf628fb47a14589c@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_link_hardreset() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case * make sata_set_spd_needed() static Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 33909 572 40 34521 86d9 drivers/ata/libata-core.o after: 33574 572 40 34186 858a drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 115 ++++++++++++++++++++++++++++++++- drivers/ata/libata-core.c | 113 -------------------------------- drivers/ata/libata.h | 2 - include/linux/libata.h | 16 ++++- 4 files changed, 127 insertions(+), 119 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 73f8be386a44..b43207396829 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -405,7 +405,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) * RETURNS: * 1 if SATA spd configuration is needed, 0 otherwise. */ -int sata_set_spd_needed(struct ata_link *link) +static int sata_set_spd_needed(struct ata_link *link) { u32 scontrol; @@ -659,6 +659,119 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, } EXPORT_SYMBOL_GPL(sata_link_scr_lpm); +/** + * sata_link_hardreset - reset link via SATA phy reset + * @link: link to reset + * @timing: timing parameters { interval, duration, timeout } in msec + * @deadline: deadline jiffies for the operation + * @online: optional out parameter indicating link onlineness + * @check_ready: optional callback to check link readiness + * + * SATA phy-reset @link using DET bits of SControl register. + * After hardreset, link readiness is waited upon using + * ata_wait_ready() if @check_ready is specified. LLDs are + * allowed to not specify @check_ready and wait itself after this + * function returns. Device classification is LLD's + * responsibility. + * + * *@online is set to one iff reset succeeded and @link is online + * after reset. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, + unsigned long deadline, + bool *online, int (*check_ready)(struct ata_link *)) +{ + u32 scontrol; + int rc; + + DPRINTK("ENTER\n"); + + if (online) + *online = false; + + if (sata_set_spd_needed(link)) { + /* SATA spec says nothing about how to reconfigure + * spd. To be on the safe side, turn off phy during + * reconfiguration. This works for at least ICH7 AHCI + * and Sil3124. + */ + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + goto out; + + scontrol = (scontrol & 0x0f0) | 0x304; + + if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) + goto out; + + sata_set_spd(link); + } + + /* issue phy wake/reset */ + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + goto out; + + scontrol = (scontrol & 0x0f0) | 0x301; + + if ((rc = sata_scr_write_flush(link, SCR_CONTROL, scontrol))) + goto out; + + /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 + * 10.4.2 says at least 1 ms. + */ + ata_msleep(link->ap, 1); + + /* bring link back */ + rc = sata_link_resume(link, timing, deadline); + if (rc) + goto out; + /* if link is offline nothing more to do */ + if (ata_phys_link_offline(link)) + goto out; + + /* Link is online. From this point, -ENODEV too is an error. */ + if (online) + *online = true; + + if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) { + /* If PMP is supported, we have to do follow-up SRST. + * Some PMPs don't send D2H Reg FIS after hardreset if + * the first port is empty. Wait only for + * ATA_TMOUT_PMP_SRST_WAIT. + */ + if (check_ready) { + unsigned long pmp_deadline; + + pmp_deadline = ata_deadline(jiffies, + ATA_TMOUT_PMP_SRST_WAIT); + if (time_after(pmp_deadline, deadline)) + pmp_deadline = deadline; + ata_wait_ready(link, pmp_deadline, check_ready); + } + rc = -EAGAIN; + goto out; + } + + rc = 0; + if (check_ready) + rc = ata_wait_ready(link, deadline, check_ready); + out: + if (rc && rc != -EAGAIN) { + /* online is set iff link is online && reset succeeded */ + if (online) + *online = false; + ata_link_err(link, "COMRESET failed (errno=%d)\n", rc); + } + DPRINTK("EXIT, rc=%d\n", rc); + return rc; +} +EXPORT_SYMBOL_GPL(sata_link_hardreset); + /** * ata_slave_link_init - initialize slave link * @ap: port to initialize slave link for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d3587fb1e78c..bd82cab2996e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3236,119 +3236,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) } EXPORT_SYMBOL_GPL(ata_std_prereset); -/** - * sata_link_hardreset - reset link via SATA phy reset - * @link: link to reset - * @timing: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * @online: optional out parameter indicating link onlineness - * @check_ready: optional callback to check link readiness - * - * SATA phy-reset @link using DET bits of SControl register. - * After hardreset, link readiness is waited upon using - * ata_wait_ready() if @check_ready is specified. LLDs are - * allowed to not specify @check_ready and wait itself after this - * function returns. Device classification is LLD's - * responsibility. - * - * *@online is set to one iff reset succeeded and @link is online - * after reset. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, - unsigned long deadline, - bool *online, int (*check_ready)(struct ata_link *)) -{ - u32 scontrol; - int rc; - - DPRINTK("ENTER\n"); - - if (online) - *online = false; - - if (sata_set_spd_needed(link)) { - /* SATA spec says nothing about how to reconfigure - * spd. To be on the safe side, turn off phy during - * reconfiguration. This works for at least ICH7 AHCI - * and Sil3124. - */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - goto out; - - scontrol = (scontrol & 0x0f0) | 0x304; - - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - goto out; - - sata_set_spd(link); - } - - /* issue phy wake/reset */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - goto out; - - scontrol = (scontrol & 0x0f0) | 0x301; - - if ((rc = sata_scr_write_flush(link, SCR_CONTROL, scontrol))) - goto out; - - /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 - * 10.4.2 says at least 1 ms. - */ - ata_msleep(link->ap, 1); - - /* bring link back */ - rc = sata_link_resume(link, timing, deadline); - if (rc) - goto out; - /* if link is offline nothing more to do */ - if (ata_phys_link_offline(link)) - goto out; - - /* Link is online. From this point, -ENODEV too is an error. */ - if (online) - *online = true; - - if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) { - /* If PMP is supported, we have to do follow-up SRST. - * Some PMPs don't send D2H Reg FIS after hardreset if - * the first port is empty. Wait only for - * ATA_TMOUT_PMP_SRST_WAIT. - */ - if (check_ready) { - unsigned long pmp_deadline; - - pmp_deadline = ata_deadline(jiffies, - ATA_TMOUT_PMP_SRST_WAIT); - if (time_after(pmp_deadline, deadline)) - pmp_deadline = deadline; - ata_wait_ready(link, pmp_deadline, check_ready); - } - rc = -EAGAIN; - goto out; - } - - rc = 0; - if (check_ready) - rc = ata_wait_ready(link, deadline, check_ready); - out: - if (rc && rc != -EAGAIN) { - /* online is set iff link is online && reset succeeded */ - if (online) - *online = false; - ata_link_err(link, "COMRESET failed (errno=%d)\n", rc); - } - DPRINTK("EXIT, rc=%d\n", rc); - return rc; -} -EXPORT_SYMBOL_GPL(sata_link_hardreset); - /** * sata_std_hardreset - COMRESET w/o waiting or classification * @link: link to reset diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index ea614ac10c76..518a8e08a26d 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -108,7 +108,6 @@ int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); void sata_print_link_status(struct ata_link *link); int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); -int sata_set_spd_needed(struct ata_link *link); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -122,7 +121,6 @@ static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) { return -EOPNOTSUPP; } -static inline int sata_set_spd_needed(struct ata_link *link) { return 1; } #endif /* libata-acpi.c */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 8a11ae3a019f..453322cdf64a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1079,9 +1079,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); -extern int sata_link_hardreset(struct ata_link *link, - const unsigned long *timing, unsigned long deadline, - bool *online, int (*check_ready)(struct ata_link *)); extern int sata_std_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); @@ -1198,6 +1195,9 @@ extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup); +extern int sata_link_hardreset(struct ata_link *link, + const unsigned long *timing, unsigned long deadline, + bool *online, int (*check_ready)(struct ata_link *)); extern int ata_slave_link_init(struct ata_port *ap); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); @@ -1211,6 +1211,16 @@ static inline int sata_link_resume(struct ata_link *link, { return -EOPNOTSUPP; } +static inline int sata_link_hardreset(struct ata_link *link, + const unsigned long *timing, + unsigned long deadline, + bool *online, + int (*check_ready)(struct ata_link *)) +{ + if (online) + *online = false; + return -EOPNOTSUPP; +} #endif extern int ata_cable_40wire(struct ata_port *ap); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133417eucas1p28b1e3fbb20c686bd75997f5339993071@eucas1p2.samsung.com>]
* [PATCH 20/28] ata: move sata_link_init_spd() to libata-core-sata.c [not found] ` <CGME20200128133417eucas1p28b1e3fbb20c686bd75997f5339993071@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_link_init_spd() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case * cover ata_force_link_limits() with CONFIG_SATA_HOST ifdef (it depends on code from libata-core.c while its only user is in libata-core-sata.c) Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 33574 572 40 34186 858a drivers/ata/libata-core.o after: 33212 572 40 33824 8420 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 33 ++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 37 +++------------------------------- drivers/ata/libata.h | 7 ++++++- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index b43207396829..8c6ed82dc166 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -772,6 +772,39 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, } EXPORT_SYMBOL_GPL(sata_link_hardreset); +/** + * sata_link_init_spd - Initialize link->sata_spd_limit + * @link: Link to configure sata_spd_limit for + * + * Initialize @link->[hw_]sata_spd_limit to the currently + * configured value. + * + * LOCKING: + * Kernel thread context (may sleep). + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int sata_link_init_spd(struct ata_link *link) +{ + u8 spd; + int rc; + + rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol); + if (rc) + return rc; + + spd = (link->saved_scontrol >> 4) & 0xf; + if (spd) + link->hw_sata_spd_limit &= (1 << spd) - 1; + + ata_force_link_limits(link); + + link->sata_spd_limit = link->hw_sata_spd_limit; + + return 0; +} + /** * ata_slave_link_init - initialize slave link * @ap: port to initialize slave link for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index bd82cab2996e..17f1d98eab71 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -338,6 +338,7 @@ void ata_force_cbl(struct ata_port *ap) } } +#ifdef CONFIG_SATA_HOST /** * ata_force_link_limits - force link limits according to libata.force * @link: ATA link of interest @@ -354,7 +355,7 @@ void ata_force_cbl(struct ata_port *ap) * LOCKING: * EH context. */ -static void ata_force_link_limits(struct ata_link *link) +void ata_force_link_limits(struct ata_link *link) { bool did_spd = false; int linkno = link->pmp; @@ -389,6 +390,7 @@ static void ata_force_link_limits(struct ata_link *link) } } } +#endif /** * ata_force_xfermask - force xfermask according to libata.force @@ -5078,39 +5080,6 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp) } } -/** - * sata_link_init_spd - Initialize link->sata_spd_limit - * @link: Link to configure sata_spd_limit for - * - * Initialize @link->[hw_]sata_spd_limit to the currently - * configured value. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_link_init_spd(struct ata_link *link) -{ - u8 spd; - int rc; - - rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol); - if (rc) - return rc; - - spd = (link->saved_scontrol >> 4) & 0xf; - if (spd) - link->hw_sata_spd_limit &= (1 << spd) - 1; - - ata_force_link_limits(link); - - link->sata_spd_limit = link->hw_sata_spd_limit; - - return 0; -} - /** * ata_port_alloc - allocate and initialize basic ATA port resources * @host: ATA host this allocated port belongs to diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 518a8e08a26d..8f5da7be88fe 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -76,7 +76,6 @@ extern bool ata_phys_link_online(struct ata_link *link); extern bool ata_phys_link_offline(struct ata_link *link); extern void ata_dev_init(struct ata_device *dev); extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); -extern int sata_link_init_spd(struct ata_link *link); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct ata_port *ata_port_alloc(struct ata_host *host); @@ -85,6 +84,7 @@ extern int ata_port_probe(struct ata_port *ap); extern void __ata_port_probe(struct ata_port *ap); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); +extern void ata_force_link_limits(struct ata_link *link); static inline bool ata_sstatus_online(u32 sstatus) { @@ -108,6 +108,7 @@ int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); void sata_print_link_status(struct ata_link *link); int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); +int sata_link_init_spd(struct ata_link *link); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -121,6 +122,10 @@ static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) { return -EOPNOTSUPP; } +static inline int sata_link_init_spd(struct ata_link *link) +{ + return -EOPNOTSUPP; +} #endif /* libata-acpi.c */ -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133417eucas1p27f91558f4b86f6951d2f9f1ed19d84b5@eucas1p2.samsung.com>]
* [PATCH 21/28] ata: move ata_qc_complete_multiple() to libata-core-sata.c [not found] ` <CGME20200128133417eucas1p27f91558f4b86f6951d2f9f1ed19d84b5@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move ata_qc_complete_multiple() to libata-core-sata.c Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 33212 572 40 33824 8420 drivers/ata/libata-core.o after: 32815 572 40 33427 8293 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 59 ++++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 59 ---------------------------------- include/linux/libata.h | 2 +- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 8c6ed82dc166..5749aa57c352 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -772,6 +772,65 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, } EXPORT_SYMBOL_GPL(sata_link_hardreset); +/** + * ata_qc_complete_multiple - Complete multiple qcs successfully + * @ap: port in question + * @qc_active: new qc_active mask + * + * Complete in-flight commands. This functions is meant to be + * called from low-level driver's interrupt routine to complete + * requests normally. ap->qc_active and @qc_active is compared + * and commands are completed accordingly. + * + * Always use this function when completing multiple NCQ commands + * from IRQ handlers instead of calling ata_qc_complete() + * multiple times to keep IRQ expect status properly in sync. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * Number of completed commands on success, -errno otherwise. + */ +int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) +{ + u64 done_mask, ap_qc_active = ap->qc_active; + int nr_done = 0; + + /* + * If the internal tag is set on ap->qc_active, then we care about + * bit0 on the passed in qc_active mask. Move that bit up to match + * the internal tag. + */ + if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) { + qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL; + qc_active ^= qc_active & 0x01; + } + + done_mask = ap_qc_active ^ qc_active; + + if (unlikely(done_mask & qc_active)) { + ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n", + ap->qc_active, qc_active); + return -EINVAL; + } + + while (done_mask) { + struct ata_queued_cmd *qc; + unsigned int tag = __ffs64(done_mask); + + qc = ata_qc_from_tag(ap, tag); + if (qc) { + ata_qc_complete(qc); + nr_done++; + } + done_mask &= ~(1ULL << tag); + } + + return nr_done; +} +EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); + /** * sata_link_init_spd - Initialize link->sata_spd_limit * @link: Link to configure sata_spd_limit for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 17f1d98eab71..204e64ff4b93 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4456,65 +4456,6 @@ u64 ata_qc_get_active(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_qc_get_active); -/** - * ata_qc_complete_multiple - Complete multiple qcs successfully - * @ap: port in question - * @qc_active: new qc_active mask - * - * Complete in-flight commands. This functions is meant to be - * called from low-level driver's interrupt routine to complete - * requests normally. ap->qc_active and @qc_active is compared - * and commands are completed accordingly. - * - * Always use this function when completing multiple NCQ commands - * from IRQ handlers instead of calling ata_qc_complete() - * multiple times to keep IRQ expect status properly in sync. - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * Number of completed commands on success, -errno otherwise. - */ -int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) -{ - u64 done_mask, ap_qc_active = ap->qc_active; - int nr_done = 0; - - /* - * If the internal tag is set on ap->qc_active, then we care about - * bit0 on the passed in qc_active mask. Move that bit up to match - * the internal tag. - */ - if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) { - qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL; - qc_active ^= qc_active & 0x01; - } - - done_mask = ap_qc_active ^ qc_active; - - if (unlikely(done_mask & qc_active)) { - ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n", - ap->qc_active, qc_active); - return -EINVAL; - } - - while (done_mask) { - struct ata_queued_cmd *qc; - unsigned int tag = __ffs64(done_mask); - - qc = ata_qc_from_tag(ap, tag); - if (qc) { - ata_qc_complete(qc); - nr_done++; - } - done_mask &= ~(1ULL << tag); - } - - return nr_done; -} -EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); - /** * ata_qc_issue - issue taskfile to device * @qc: command to issue to device diff --git a/include/linux/libata.h b/include/linux/libata.h index 453322cdf64a..62e962b62c5d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1166,7 +1166,6 @@ extern void ata_id_c_string(const u16 *id, unsigned char *s, extern unsigned int ata_do_dev_read_id(struct ata_device *dev, struct ata_taskfile *tf, u16 *id); extern void ata_qc_complete(struct ata_queued_cmd *qc); -extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); extern u64 ata_qc_get_active(struct ata_port *ap); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); extern int ata_std_bios_param(struct scsi_device *sdev, @@ -1202,6 +1201,7 @@ extern int ata_slave_link_init(struct ata_port *ap); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); +extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); #else static inline int sata_set_spd(struct ata_link *link) { return -EOPNOTSUPP; } -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133418eucas1p1b28eb901c4d21446376c1028b2977017@eucas1p1.samsung.com>]
* [PATCH 22/28] ata: move sata_scr_*() to libata-core-sata.c [not found] ` <CGME20200128133418eucas1p1b28eb901c4d21446376c1028b2977017@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_scr_*() to libata-core-sata.c * add static inlines for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 32815 572 40 33427 8293 drivers/ata/libata-core.o after: 32146 572 40 32758 7ff6 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 109 +++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 109 --------------------------------- include/linux/libata.h | 21 +++++-- 3 files changed, 126 insertions(+), 113 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 5749aa57c352..a3709b356fd2 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -831,6 +831,115 @@ int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) } EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); +/** + * sata_scr_valid - test whether SCRs are accessible + * @link: ATA link to test SCR accessibility for + * + * Test whether SCRs are accessible for @link. + * + * LOCKING: + * None. + * + * RETURNS: + * 1 if SCRs are accessible, 0 otherwise. + */ +int sata_scr_valid(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + + return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read; +} +EXPORT_SYMBOL_GPL(sata_scr_valid); + +/** + * sata_scr_read - read SCR register of the specified port + * @link: ATA link to read SCR for + * @reg: SCR to read + * @val: Place to store read value + * + * Read SCR register @reg of @link into *@val. This function is + * guaranteed to succeed if @link is ap->link, the cable type of + * the port is SATA and the port implements ->scr_read. + * + * LOCKING: + * None if @link is ap->link. Kernel thread context otherwise. + * + * RETURNS: + * 0 on success, negative errno on failure. + */ +int sata_scr_read(struct ata_link *link, int reg, u32 *val) +{ + if (ata_is_host_link(link)) { + if (sata_scr_valid(link)) + return link->ap->ops->scr_read(link, reg, val); + return -EOPNOTSUPP; + } + + return sata_pmp_scr_read(link, reg, val); +} +EXPORT_SYMBOL_GPL(sata_scr_read); + +/** + * sata_scr_write - write SCR register of the specified port + * @link: ATA link to write SCR for + * @reg: SCR to write + * @val: value to write + * + * Write @val to SCR register @reg of @link. This function is + * guaranteed to succeed if @link is ap->link, the cable type of + * the port is SATA and the port implements ->scr_read. + * + * LOCKING: + * None if @link is ap->link. Kernel thread context otherwise. + * + * RETURNS: + * 0 on success, negative errno on failure. + */ +int sata_scr_write(struct ata_link *link, int reg, u32 val) +{ + if (ata_is_host_link(link)) { + if (sata_scr_valid(link)) + return link->ap->ops->scr_write(link, reg, val); + return -EOPNOTSUPP; + } + + return sata_pmp_scr_write(link, reg, val); +} +EXPORT_SYMBOL_GPL(sata_scr_write); + +/** + * sata_scr_write_flush - write SCR register of the specified port and flush + * @link: ATA link to write SCR for + * @reg: SCR to write + * @val: value to write + * + * This function is identical to sata_scr_write() except that this + * function performs flush after writing to the register. + * + * LOCKING: + * None if @link is ap->link. Kernel thread context otherwise. + * + * RETURNS: + * 0 on success, negative errno on failure. + */ +int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) +{ + if (ata_is_host_link(link)) { + int rc; + + if (sata_scr_valid(link)) { + rc = link->ap->ops->scr_write(link, reg, val); + if (rc == 0) + rc = link->ap->ops->scr_read(link, reg, &val); + return rc; + } + return -EOPNOTSUPP; + } + + return sata_pmp_scr_write(link, reg, val); +} +EXPORT_SYMBOL_GPL(sata_scr_write_flush); + /** * sata_link_init_spd - Initialize link->sata_spd_limit * @link: Link to configure sata_spd_limit for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 204e64ff4b93..f7124aede419 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4531,115 +4531,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) ata_qc_complete(qc); } -/** - * sata_scr_valid - test whether SCRs are accessible - * @link: ATA link to test SCR accessibility for - * - * Test whether SCRs are accessible for @link. - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if SCRs are accessible, 0 otherwise. - */ -int sata_scr_valid(struct ata_link *link) -{ - struct ata_port *ap = link->ap; - - return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read; -} -EXPORT_SYMBOL_GPL(sata_scr_valid); - -/** - * sata_scr_read - read SCR register of the specified port - * @link: ATA link to read SCR for - * @reg: SCR to read - * @val: Place to store read value - * - * Read SCR register @reg of @link into *@val. This function is - * guaranteed to succeed if @link is ap->link, the cable type of - * the port is SATA and the port implements ->scr_read. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_read(struct ata_link *link, int reg, u32 *val) -{ - if (ata_is_host_link(link)) { - if (sata_scr_valid(link)) - return link->ap->ops->scr_read(link, reg, val); - return -EOPNOTSUPP; - } - - return sata_pmp_scr_read(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_read); - -/** - * sata_scr_write - write SCR register of the specified port - * @link: ATA link to write SCR for - * @reg: SCR to write - * @val: value to write - * - * Write @val to SCR register @reg of @link. This function is - * guaranteed to succeed if @link is ap->link, the cable type of - * the port is SATA and the port implements ->scr_read. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_write(struct ata_link *link, int reg, u32 val) -{ - if (ata_is_host_link(link)) { - if (sata_scr_valid(link)) - return link->ap->ops->scr_write(link, reg, val); - return -EOPNOTSUPP; - } - - return sata_pmp_scr_write(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_write); - -/** - * sata_scr_write_flush - write SCR register of the specified port and flush - * @link: ATA link to write SCR for - * @reg: SCR to write - * @val: value to write - * - * This function is identical to sata_scr_write() except that this - * function performs flush after writing to the register. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) -{ - if (ata_is_host_link(link)) { - int rc; - - if (sata_scr_valid(link)) { - rc = link->ap->ops->scr_write(link, reg, val); - if (rc == 0) - rc = link->ap->ops->scr_read(link, reg, &val); - return rc; - } - return -EOPNOTSUPP; - } - - return sata_pmp_scr_write(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_write_flush); - /** * ata_phys_link_online - test whether the given link is online * @link: ATA link to test diff --git a/include/linux/libata.h b/include/linux/libata.h index 62e962b62c5d..3f5d714caa43 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1119,10 +1119,6 @@ extern void ata_sas_tport_delete(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); -extern int sata_scr_valid(struct ata_link *link); -extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); -extern int sata_scr_write(struct ata_link *link, int reg, u32 val); -extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val); extern bool ata_link_online(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM @@ -1198,6 +1194,10 @@ extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); extern int ata_slave_link_init(struct ata_port *ap); +extern int sata_scr_valid(struct ata_link *link); +extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); +extern int sata_scr_write(struct ata_link *link, int reg, u32 val); +extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); @@ -1221,6 +1221,19 @@ static inline int sata_link_hardreset(struct ata_link *link, *online = false; return -EOPNOTSUPP; } +static inline int sata_scr_valid(struct ata_link *link) { return 0; } +static inline int sata_scr_read(struct ata_link *link, int reg, u32 *val) +{ + return -EOPNOTSUPP; +} +static inline int sata_scr_write(struct ata_link *link, int reg, u32 val) +{ + return -EOPNOTSUPP; +} +static inline int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) +{ + return -EOPNOTSUPP; +} #endif extern int ata_cable_40wire(struct ata_port *ap); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133418eucas1p1fd63b12146a2848ab61db768fde77857@eucas1p1.samsung.com>]
* [PATCH 23/28] ata: move sata_deb_timing_*() to libata-core-sata.c [not found] ` <CGME20200128133418eucas1p1fd63b12146a2848ab61db768fde77857@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move sata_deb_timing_*() to libata-core-sata.c * add static inline for sata_ehc_deb_timing() for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 32146 572 40 32758 7ff6 drivers/ata/libata-core.o after: 32003 572 40 32615 7f67 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-core-sata.c | 8 ++++++++ drivers/ata/libata-core.c | 8 -------- include/linux/libata.h | 31 ++++++++++++++++++------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index a3709b356fd2..2bfbb67450f2 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -12,6 +12,14 @@ #include "libata.h" +/* debounce timing parameters in msecs { interval, duration, timeout } */ +const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_normal); +const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); +const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_long); + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f7124aede419..c7583f7e9bf0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -65,14 +65,6 @@ #include "libata.h" #include "libata-transport.h" -/* debounce timing parameters in msecs { interval, duration, timeout } */ -const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_normal); -const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); -const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_long); - const struct ata_port_operations ata_base_port_ops = { .prereset = ata_std_prereset, .postreset = ata_std_postreset, diff --git a/include/linux/libata.h b/include/linux/libata.h index 3f5d714caa43..3124cad39d50 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1021,10 +1021,6 @@ struct ata_timing { /* * Core layer - drivers/ata/libata-core.c */ -extern const unsigned long sata_deb_timing_normal[]; -extern const unsigned long sata_deb_timing_hotplug[]; -extern const unsigned long sata_deb_timing_long[]; - extern struct ata_port_operations ata_dummy_port_ops; extern const struct ata_port_info ata_dummy_port_info; @@ -1062,15 +1058,6 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf) (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); } -static inline const unsigned long * -sata_ehc_deb_timing(struct ata_eh_context *ehc) -{ - if (ehc->i.flags & ATA_EHI_HOTPLUGGED) - return sata_deb_timing_hotplug; - else - return sata_deb_timing_normal; -} - static inline int ata_port_is_dummy(struct ata_port *ap) { return ap->ops == &ata_dummy_port_ops; @@ -1183,6 +1170,19 @@ extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port * * Core layer (SATA specific part) - drivers/ata/libata-core-sata.c */ #ifdef CONFIG_SATA_HOST +extern const unsigned long sata_deb_timing_normal[]; +extern const unsigned long sata_deb_timing_hotplug[]; +extern const unsigned long sata_deb_timing_long[]; + +static inline const unsigned long * +sata_ehc_deb_timing(struct ata_eh_context *ehc) +{ + if (ehc->i.flags & ATA_EHI_HOTPLUGGED) + return sata_deb_timing_hotplug; + else + return sata_deb_timing_normal; +} + extern int sata_set_spd(struct ata_link *link); extern int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline); @@ -1204,6 +1204,11 @@ extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); #else +static inline const unsigned long * +sata_ehc_deb_timing(struct ata_eh_context *ehc) +{ + return NULL; +} static inline int sata_set_spd(struct ata_link *link) { return -EOPNOTSUPP; } static inline int sata_link_resume(struct ata_link *link, const unsigned long *params, -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133418eucas1p157933935f14f9c83c604bc5dc38bcbae@eucas1p1.samsung.com>]
* [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c [not found] ` <CGME20200128133418eucas1p157933935f14f9c83c604bc5dc38bcbae@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 2020-01-29 11:13 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:31 ` Christoph Hellwig 0 siblings, 2 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie Start separating SATA specific code from libata-scsi.c: * un-static ata_scsi_find_dev() * move following code to libata-scsi-sata.c: - SATA only sysfs device attributes handling - __ata_change_queue_depth() - ata_scsi_change_queue_depth() * cover with CONFIG_SATA_HOST ifdef SATA only sysfs device attributes handling code and ATA_SHT_NCQ() macro in <linux/libata.h> * include libata-scsi-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: 20702 105 4096 24903 6147 drivers/ata/libata-scsi.o after: 19137 23 4096 23256 5ad8 drivers/ata/libata-scsi.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/Makefile | 2 +- drivers/ata/libata-scsi-sata.c | 310 +++++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 301 +------------------------------- drivers/ata/libata.h | 2 + include/linux/libata.h | 9 +- 5 files changed, 321 insertions(+), 303 deletions(-) create mode 100644 drivers/ata/libata-scsi-sata.c diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b06b9a211691..d6fb3d4a2ac5 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -123,7 +123,7 @@ 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-$(CONFIG_SATA_HOST) += libata-core-sata.o libata-scsi-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-scsi-sata.c b/drivers/ata/libata-scsi-sata.c new file mode 100644 index 000000000000..da7d8344d003 --- /dev/null +++ b/drivers/ata/libata-scsi-sata.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * libata-scsi-sata.c - SATA specific part of ATA helper library + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + */ + +#include <linux/kernel.h> +#include <scsi/scsi_device.h> +#include <linux/libata.h> + +#include "libata.h" + +static const char *ata_lpm_policy_names[] = { + [ATA_LPM_UNKNOWN] = "max_performance", + [ATA_LPM_MAX_POWER] = "max_performance", + [ATA_LPM_MED_POWER] = "medium_power", + [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", + [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", + [ATA_LPM_MIN_POWER] = "min_power", +}; + +static ssize_t ata_scsi_lpm_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(device); + struct ata_port *ap = ata_shost_to_port(shost); + struct ata_link *link; + struct ata_device *dev; + enum ata_lpm_policy policy; + unsigned long flags; + + /* UNKNOWN is internal state, iterate from MAX_POWER */ + for (policy = ATA_LPM_MAX_POWER; + policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { + const char *name = ata_lpm_policy_names[policy]; + + if (strncmp(name, buf, strlen(name)) == 0) + break; + } + if (policy == ARRAY_SIZE(ata_lpm_policy_names)) + return -EINVAL; + + spin_lock_irqsave(ap->lock, flags); + + ata_for_each_link(link, ap, EDGE) { + ata_for_each_dev(dev, &ap->link, ENABLED) { + if (dev->horkage & ATA_HORKAGE_NOLPM) { + count = -EOPNOTSUPP; + goto out_unlock; + } + } + } + + ap->target_lpm_policy = policy; + ata_port_schedule_eh(ap); +out_unlock: + spin_unlock_irqrestore(ap->lock, flags); + return count; +} + +static ssize_t ata_scsi_lpm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) + return -EINVAL; + + return snprintf(buf, PAGE_SIZE, "%s\n", + ata_lpm_policy_names[ap->target_lpm_policy]); +} +DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, + ata_scsi_lpm_show, ata_scsi_lpm_store); +EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); + +static ssize_t ata_ncq_prio_enable_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct ata_port *ap; + struct ata_device *dev; + bool ncq_prio_enable; + int rc = 0; + + ap = ata_shost_to_port(sdev->host); + + spin_lock_irq(ap->lock); + dev = ata_scsi_find_dev(ap, sdev); + if (!dev) { + rc = -ENODEV; + goto unlock; + } + + ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; + +unlock: + spin_unlock_irq(ap->lock); + + return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); +} + +static ssize_t ata_ncq_prio_enable_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct ata_port *ap; + struct ata_device *dev; + long int input; + int rc; + + rc = kstrtol(buf, 10, &input); + if (rc) + return rc; + if ((input < 0) || (input > 1)) + return -EINVAL; + + ap = ata_shost_to_port(sdev->host); + dev = ata_scsi_find_dev(ap, sdev); + if (unlikely(!dev)) + return -ENODEV; + + spin_lock_irq(ap->lock); + if (input) + dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; + else + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; + + dev->link->eh_info.action |= ATA_EH_REVALIDATE; + dev->link->eh_info.flags |= ATA_EHI_QUIET; + ata_port_schedule_eh(ap); + spin_unlock_irq(ap->lock); + + ata_port_wait_eh(ap); + + if (input) { + spin_lock_irq(ap->lock); + if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; + rc = -EIO; + } + spin_unlock_irq(ap->lock); + } + + return rc ? rc : len; +} + +DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, + ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); +EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); + +struct device_attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads, + &dev_attr_ncq_prio_enable, + NULL +}; +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); + +static ssize_t +ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_store(ap, buf, count); + return -EINVAL; +} + +static ssize_t +ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_show(ap, buf); + return -EINVAL; +} +DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, + ata_scsi_em_message_show, ata_scsi_em_message_store); +EXPORT_SYMBOL_GPL(dev_attr_em_message); + +static ssize_t +ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + return snprintf(buf, 23, "%d\n", ap->em_message_type); +} +DEVICE_ATTR(em_message_type, S_IRUGO, + ata_scsi_em_message_type_show, NULL); +EXPORT_SYMBOL_GPL(dev_attr_em_message_type); + +static ssize_t +ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + + if (atadev && ap->ops->sw_activity_show && + (ap->flags & ATA_FLAG_SW_ACTIVITY)) + return ap->ops->sw_activity_show(atadev, buf); + return -EINVAL; +} + +static ssize_t +ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + enum sw_activity val; + int rc; + + if (atadev && ap->ops->sw_activity_store && + (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + val = simple_strtoul(buf, NULL, 0); + switch (val) { + case OFF: case BLINK_ON: case BLINK_OFF: + rc = ap->ops->sw_activity_store(atadev, val); + if (!rc) + return count; + else + return rc; + } + } + return -EINVAL; +} +DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, + ata_scsi_activity_store); +EXPORT_SYMBOL_GPL(dev_attr_sw_activity); + +/** + * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth + * @ap: ATA port to which the device change the queue depth + * @sdev: SCSI device to configure queue depth for + * @queue_depth: new queue depth + * + * libsas and libata have different approaches for associating a sdev to + * its ata_port. + * + */ +int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, + int queue_depth) +{ + struct ata_device *dev; + unsigned long flags; + + if (queue_depth < 1 || queue_depth == sdev->queue_depth) + return sdev->queue_depth; + + dev = ata_scsi_find_dev(ap, sdev); + if (!dev || !ata_dev_enabled(dev)) + return sdev->queue_depth; + + /* NCQ enabled? */ + spin_lock_irqsave(ap->lock, flags); + dev->flags &= ~ATA_DFLAG_NCQ_OFF; + if (queue_depth == 1 || !ata_ncq_enabled(dev)) { + dev->flags |= ATA_DFLAG_NCQ_OFF; + queue_depth = 1; + } + spin_unlock_irqrestore(ap->lock, flags); + + /* limit and apply queue depth */ + queue_depth = min(queue_depth, sdev->host->can_queue); + queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); + queue_depth = min(queue_depth, ATA_MAX_QUEUE); + + if (sdev->queue_depth == queue_depth) + return -EINVAL; + + return scsi_change_queue_depth(sdev, queue_depth); +} +EXPORT_SYMBOL_GPL(__ata_change_queue_depth); + +/** + * ata_scsi_change_queue_depth - SCSI callback for queue depth config + * @sdev: SCSI device to configure queue depth for + * @queue_depth: new queue depth + * + * This is libata standard hostt->change_queue_depth callback. + * SCSI will call into this callback when user tries to set queue + * depth via sysfs. + * + * LOCKING: + * SCSI layer (we don't care) + * + * RETURNS: + * Newly configured queue depth. + */ +int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) +{ + struct ata_port *ap = ata_shost_to_port(sdev->host); + + return __ata_change_queue_depth(ap, sdev, queue_depth); +} +EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d549bd5b3d36..82c398c93379 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -45,8 +45,6 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); -static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev); #define RW_RECOVERY_MPAGE 0x1 #define RW_RECOVERY_MPAGE_LEN 12 @@ -86,71 +84,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { 0, 30 /* extended self test time, see 05-359r1 */ }; -static const char *ata_lpm_policy_names[] = { - [ATA_LPM_UNKNOWN] = "max_performance", - [ATA_LPM_MAX_POWER] = "max_performance", - [ATA_LPM_MED_POWER] = "medium_power", - [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", - [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", - [ATA_LPM_MIN_POWER] = "min_power", -}; - -static ssize_t ata_scsi_lpm_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(device); - struct ata_port *ap = ata_shost_to_port(shost); - struct ata_link *link; - struct ata_device *dev; - enum ata_lpm_policy policy; - unsigned long flags; - - /* UNKNOWN is internal state, iterate from MAX_POWER */ - for (policy = ATA_LPM_MAX_POWER; - policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { - const char *name = ata_lpm_policy_names[policy]; - - if (strncmp(name, buf, strlen(name)) == 0) - break; - } - if (policy == ARRAY_SIZE(ata_lpm_policy_names)) - return -EINVAL; - - spin_lock_irqsave(ap->lock, flags); - - ata_for_each_link(link, ap, EDGE) { - ata_for_each_dev(dev, &ap->link, ENABLED) { - if (dev->horkage & ATA_HORKAGE_NOLPM) { - count = -EOPNOTSUPP; - goto out_unlock; - } - } - } - - ap->target_lpm_policy = policy; - ata_port_schedule_eh(ap); -out_unlock: - spin_unlock_irqrestore(ap->lock, flags); - return count; -} - -static ssize_t ata_scsi_lpm_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) - return -EINVAL; - - return snprintf(buf, PAGE_SIZE, "%s\n", - ata_lpm_policy_names[ap->target_lpm_policy]); -} -DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, - ata_scsi_lpm_show, ata_scsi_lpm_store); -EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); - static ssize_t ata_scsi_park_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -254,83 +187,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ata_scsi_park_show, ata_scsi_park_store); EXPORT_SYMBOL_GPL(dev_attr_unload_heads); -static ssize_t ata_ncq_prio_enable_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct scsi_device *sdev = to_scsi_device(device); - struct ata_port *ap; - struct ata_device *dev; - bool ncq_prio_enable; - int rc = 0; - - ap = ata_shost_to_port(sdev->host); - - spin_lock_irq(ap->lock); - dev = ata_scsi_find_dev(ap, sdev); - if (!dev) { - rc = -ENODEV; - goto unlock; - } - - ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; - -unlock: - spin_unlock_irq(ap->lock); - - return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); -} - -static ssize_t ata_ncq_prio_enable_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct scsi_device *sdev = to_scsi_device(device); - struct ata_port *ap; - struct ata_device *dev; - long int input; - int rc; - - rc = kstrtol(buf, 10, &input); - if (rc) - return rc; - if ((input < 0) || (input > 1)) - return -EINVAL; - - ap = ata_shost_to_port(sdev->host); - dev = ata_scsi_find_dev(ap, sdev); - if (unlikely(!dev)) - return -ENODEV; - - spin_lock_irq(ap->lock); - if (input) - dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; - else - dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; - - dev->link->eh_info.action |= ATA_EH_REVALIDATE; - dev->link->eh_info.flags |= ATA_EHI_QUIET; - ata_port_schedule_eh(ap); - spin_unlock_irq(ap->lock); - - ata_port_wait_eh(ap); - - if (input) { - spin_lock_irq(ap->lock); - if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; - rc = -EIO; - } - spin_unlock_irq(ap->lock); - } - - return rc ? rc : len; -} - -DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, - ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); -EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); - void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) { @@ -379,100 +235,12 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, field, 0xff, 0); } -static ssize_t -ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_store(ap, buf, count); - return -EINVAL; -} - -static ssize_t -ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_show(ap, buf); - return -EINVAL; -} -DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, - ata_scsi_em_message_show, ata_scsi_em_message_store); -EXPORT_SYMBOL_GPL(dev_attr_em_message); - -static ssize_t -ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - return snprintf(buf, 23, "%d\n", ap->em_message_type); -} -DEVICE_ATTR(em_message_type, S_IRUGO, - ata_scsi_em_message_type_show, NULL); -EXPORT_SYMBOL_GPL(dev_attr_em_message_type); - -static ssize_t -ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - - if (atadev && ap->ops->sw_activity_show && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) - return ap->ops->sw_activity_show(atadev, buf); - return -EINVAL; -} - -static ssize_t -ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - enum sw_activity val; - int rc; - - if (atadev && ap->ops->sw_activity_store && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) { - val = simple_strtoul(buf, NULL, 0); - switch (val) { - case OFF: case BLINK_ON: case BLINK_OFF: - rc = ap->ops->sw_activity_store(atadev, val); - if (!rc) - return count; - else - return rc; - } - } - return -EINVAL; -} -DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, - ata_scsi_activity_store); -EXPORT_SYMBOL_GPL(dev_attr_sw_activity); - struct device_attribute *ata_common_sdev_attrs[] = { &dev_attr_unload_heads, NULL }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -struct device_attribute *ata_ncq_sdev_attrs[] = { - &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, - NULL -}; -EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); - /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined @@ -1390,73 +1158,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) } EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); -/** - * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth - * @ap: ATA port to which the device change the queue depth - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * libsas and libata have different approaches for associating a sdev to - * its ata_port. - * - */ -int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth) -{ - struct ata_device *dev; - unsigned long flags; - - if (queue_depth < 1 || queue_depth == sdev->queue_depth) - return sdev->queue_depth; - - dev = ata_scsi_find_dev(ap, sdev); - if (!dev || !ata_dev_enabled(dev)) - return sdev->queue_depth; - - /* NCQ enabled? */ - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - if (queue_depth == 1 || !ata_ncq_enabled(dev)) { - dev->flags |= ATA_DFLAG_NCQ_OFF; - queue_depth = 1; - } - spin_unlock_irqrestore(ap->lock, flags); - - /* limit and apply queue depth */ - queue_depth = min(queue_depth, sdev->host->can_queue); - queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); - queue_depth = min(queue_depth, ATA_MAX_QUEUE); - - if (sdev->queue_depth == queue_depth) - return -EINVAL; - - return scsi_change_queue_depth(sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(__ata_change_queue_depth); - -/** - * ata_scsi_change_queue_depth - SCSI callback for queue depth config - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * This is libata standard hostt->change_queue_depth callback. - * SCSI will call into this callback when user tries to set queue - * depth via sysfs. - * - * LOCKING: - * SCSI layer (we don't care) - * - * RETURNS: - * Newly configured queue depth. - */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) -{ - struct ata_port *ap = ata_shost_to_port(sdev->host); - - return __ata_change_queue_depth(ap, sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); - /** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * @qc: Storage for translated ATA taskfile @@ -3093,7 +2794,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, * RETURNS: * Associated ATA device, or %NULL if not found. */ -static struct ata_device * +struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) { struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 8f5da7be88fe..2c479e48c4c9 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -153,6 +153,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} #endif /* libata-scsi.c */ +extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap, + const struct scsi_device *scsidev); extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); diff --git a/include/linux/libata.h b/include/linux/libata.h index 3124cad39d50..4b6ac3eda0c9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -532,12 +532,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes, unsigned long deadline); typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); -extern struct device_attribute dev_attr_link_power_management_policy; extern struct device_attribute dev_attr_unload_heads; +#ifdef CONFIG_SATA_HOST +extern struct device_attribute dev_attr_link_power_management_policy; extern struct device_attribute dev_attr_ncq_prio_enable; extern struct device_attribute dev_attr_em_message_type; extern struct device_attribute dev_attr_em_message; extern struct device_attribute dev_attr_sw_activity; +#endif enum sw_activity { OFF, @@ -1374,7 +1376,6 @@ extern int ata_link_nr_enabled(struct ata_link *link); extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; extern struct device_attribute *ata_common_sdev_attrs[]; -extern struct device_attribute *ata_ncq_sdev_attrs[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1399,10 +1400,14 @@ extern struct device_attribute *ata_ncq_sdev_attrs[]; .unlock_native_capacity = ata_scsi_unlock_native_capacity, \ .sdev_attrs = ata_common_sdev_attrs +#ifdef CONFIG_SATA_HOST +extern struct device_attribute *ata_ncq_sdev_attrs[]; + #define ATA_NCQ_SHT(drv_name) \ ATA_BASE_SHT(drv_name), \ .sdev_attrs = ata_ncq_sdev_attrs \ .change_queue_depth = ata_scsi_change_queue_depth +#endif /* * PMP helpers -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c 2020-01-28 13:33 ` [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c Bartlomiej Zolnierkiewicz @ 2020-01-29 11:13 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:31 ` Christoph Hellwig 1 sibling, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-29 11:13 UTC (permalink / raw) To: Jens Axboe; +Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel Start separating SATA specific code from libata-scsi.c: * un-static ata_scsi_find_dev() * move following code to libata-scsi-sata.c: - SATA only sysfs device attributes handling - __ata_change_queue_depth() - ata_scsi_change_queue_depth() * cover with CONFIG_SATA_HOST ifdef SATA only sysfs device attributes handling code and ATA_SHT_NCQ() macro in <linux/libata.h> * include libata-scsi-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: 20702 105 4096 24903 6147 drivers/ata/libata-scsi.o after: 19137 23 4096 23256 5ad8 drivers/ata/libata-scsi.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- v1.5, the v1 didn't apply (by mistake I've included old patch version which missed coma in ATA_NCQ_SHT() macro), sorry for that drivers/ata/Makefile | 2 +- drivers/ata/libata-scsi-sata.c | 310 +++++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 301 +------------------------------- drivers/ata/libata.h | 2 + include/linux/libata.h | 9 +- 5 files changed, 321 insertions(+), 303 deletions(-) create mode 100644 drivers/ata/libata-scsi-sata.c diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b06b9a211691..d6fb3d4a2ac5 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -123,7 +123,7 @@ 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-$(CONFIG_SATA_HOST) += libata-core-sata.o libata-scsi-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-scsi-sata.c b/drivers/ata/libata-scsi-sata.c new file mode 100644 index 000000000000..da7d8344d003 --- /dev/null +++ b/drivers/ata/libata-scsi-sata.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * libata-scsi-sata.c - SATA specific part of ATA helper library + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + */ + +#include <linux/kernel.h> +#include <scsi/scsi_device.h> +#include <linux/libata.h> + +#include "libata.h" + +static const char *ata_lpm_policy_names[] = { + [ATA_LPM_UNKNOWN] = "max_performance", + [ATA_LPM_MAX_POWER] = "max_performance", + [ATA_LPM_MED_POWER] = "medium_power", + [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", + [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", + [ATA_LPM_MIN_POWER] = "min_power", +}; + +static ssize_t ata_scsi_lpm_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(device); + struct ata_port *ap = ata_shost_to_port(shost); + struct ata_link *link; + struct ata_device *dev; + enum ata_lpm_policy policy; + unsigned long flags; + + /* UNKNOWN is internal state, iterate from MAX_POWER */ + for (policy = ATA_LPM_MAX_POWER; + policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { + const char *name = ata_lpm_policy_names[policy]; + + if (strncmp(name, buf, strlen(name)) == 0) + break; + } + if (policy == ARRAY_SIZE(ata_lpm_policy_names)) + return -EINVAL; + + spin_lock_irqsave(ap->lock, flags); + + ata_for_each_link(link, ap, EDGE) { + ata_for_each_dev(dev, &ap->link, ENABLED) { + if (dev->horkage & ATA_HORKAGE_NOLPM) { + count = -EOPNOTSUPP; + goto out_unlock; + } + } + } + + ap->target_lpm_policy = policy; + ata_port_schedule_eh(ap); +out_unlock: + spin_unlock_irqrestore(ap->lock, flags); + return count; +} + +static ssize_t ata_scsi_lpm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) + return -EINVAL; + + return snprintf(buf, PAGE_SIZE, "%s\n", + ata_lpm_policy_names[ap->target_lpm_policy]); +} +DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, + ata_scsi_lpm_show, ata_scsi_lpm_store); +EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); + +static ssize_t ata_ncq_prio_enable_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct ata_port *ap; + struct ata_device *dev; + bool ncq_prio_enable; + int rc = 0; + + ap = ata_shost_to_port(sdev->host); + + spin_lock_irq(ap->lock); + dev = ata_scsi_find_dev(ap, sdev); + if (!dev) { + rc = -ENODEV; + goto unlock; + } + + ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; + +unlock: + spin_unlock_irq(ap->lock); + + return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); +} + +static ssize_t ata_ncq_prio_enable_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct ata_port *ap; + struct ata_device *dev; + long int input; + int rc; + + rc = kstrtol(buf, 10, &input); + if (rc) + return rc; + if ((input < 0) || (input > 1)) + return -EINVAL; + + ap = ata_shost_to_port(sdev->host); + dev = ata_scsi_find_dev(ap, sdev); + if (unlikely(!dev)) + return -ENODEV; + + spin_lock_irq(ap->lock); + if (input) + dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; + else + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; + + dev->link->eh_info.action |= ATA_EH_REVALIDATE; + dev->link->eh_info.flags |= ATA_EHI_QUIET; + ata_port_schedule_eh(ap); + spin_unlock_irq(ap->lock); + + ata_port_wait_eh(ap); + + if (input) { + spin_lock_irq(ap->lock); + if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; + rc = -EIO; + } + spin_unlock_irq(ap->lock); + } + + return rc ? rc : len; +} + +DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, + ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); +EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); + +struct device_attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads, + &dev_attr_ncq_prio_enable, + NULL +}; +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); + +static ssize_t +ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_store(ap, buf, count); + return -EINVAL; +} + +static ssize_t +ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_show(ap, buf); + return -EINVAL; +} +DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, + ata_scsi_em_message_show, ata_scsi_em_message_store); +EXPORT_SYMBOL_GPL(dev_attr_em_message); + +static ssize_t +ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + return snprintf(buf, 23, "%d\n", ap->em_message_type); +} +DEVICE_ATTR(em_message_type, S_IRUGO, + ata_scsi_em_message_type_show, NULL); +EXPORT_SYMBOL_GPL(dev_attr_em_message_type); + +static ssize_t +ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + + if (atadev && ap->ops->sw_activity_show && + (ap->flags & ATA_FLAG_SW_ACTIVITY)) + return ap->ops->sw_activity_show(atadev, buf); + return -EINVAL; +} + +static ssize_t +ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + enum sw_activity val; + int rc; + + if (atadev && ap->ops->sw_activity_store && + (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + val = simple_strtoul(buf, NULL, 0); + switch (val) { + case OFF: case BLINK_ON: case BLINK_OFF: + rc = ap->ops->sw_activity_store(atadev, val); + if (!rc) + return count; + else + return rc; + } + } + return -EINVAL; +} +DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, + ata_scsi_activity_store); +EXPORT_SYMBOL_GPL(dev_attr_sw_activity); + +/** + * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth + * @ap: ATA port to which the device change the queue depth + * @sdev: SCSI device to configure queue depth for + * @queue_depth: new queue depth + * + * libsas and libata have different approaches for associating a sdev to + * its ata_port. + * + */ +int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, + int queue_depth) +{ + struct ata_device *dev; + unsigned long flags; + + if (queue_depth < 1 || queue_depth == sdev->queue_depth) + return sdev->queue_depth; + + dev = ata_scsi_find_dev(ap, sdev); + if (!dev || !ata_dev_enabled(dev)) + return sdev->queue_depth; + + /* NCQ enabled? */ + spin_lock_irqsave(ap->lock, flags); + dev->flags &= ~ATA_DFLAG_NCQ_OFF; + if (queue_depth == 1 || !ata_ncq_enabled(dev)) { + dev->flags |= ATA_DFLAG_NCQ_OFF; + queue_depth = 1; + } + spin_unlock_irqrestore(ap->lock, flags); + + /* limit and apply queue depth */ + queue_depth = min(queue_depth, sdev->host->can_queue); + queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); + queue_depth = min(queue_depth, ATA_MAX_QUEUE); + + if (sdev->queue_depth == queue_depth) + return -EINVAL; + + return scsi_change_queue_depth(sdev, queue_depth); +} +EXPORT_SYMBOL_GPL(__ata_change_queue_depth); + +/** + * ata_scsi_change_queue_depth - SCSI callback for queue depth config + * @sdev: SCSI device to configure queue depth for + * @queue_depth: new queue depth + * + * This is libata standard hostt->change_queue_depth callback. + * SCSI will call into this callback when user tries to set queue + * depth via sysfs. + * + * LOCKING: + * SCSI layer (we don't care) + * + * RETURNS: + * Newly configured queue depth. + */ +int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) +{ + struct ata_port *ap = ata_shost_to_port(sdev->host); + + return __ata_change_queue_depth(ap, sdev, queue_depth); +} +EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d549bd5b3d36..82c398c93379 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -45,8 +45,6 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); -static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev); #define RW_RECOVERY_MPAGE 0x1 #define RW_RECOVERY_MPAGE_LEN 12 @@ -86,71 +84,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { 0, 30 /* extended self test time, see 05-359r1 */ }; -static const char *ata_lpm_policy_names[] = { - [ATA_LPM_UNKNOWN] = "max_performance", - [ATA_LPM_MAX_POWER] = "max_performance", - [ATA_LPM_MED_POWER] = "medium_power", - [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", - [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial", - [ATA_LPM_MIN_POWER] = "min_power", -}; - -static ssize_t ata_scsi_lpm_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(device); - struct ata_port *ap = ata_shost_to_port(shost); - struct ata_link *link; - struct ata_device *dev; - enum ata_lpm_policy policy; - unsigned long flags; - - /* UNKNOWN is internal state, iterate from MAX_POWER */ - for (policy = ATA_LPM_MAX_POWER; - policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { - const char *name = ata_lpm_policy_names[policy]; - - if (strncmp(name, buf, strlen(name)) == 0) - break; - } - if (policy == ARRAY_SIZE(ata_lpm_policy_names)) - return -EINVAL; - - spin_lock_irqsave(ap->lock, flags); - - ata_for_each_link(link, ap, EDGE) { - ata_for_each_dev(dev, &ap->link, ENABLED) { - if (dev->horkage & ATA_HORKAGE_NOLPM) { - count = -EOPNOTSUPP; - goto out_unlock; - } - } - } - - ap->target_lpm_policy = policy; - ata_port_schedule_eh(ap); -out_unlock: - spin_unlock_irqrestore(ap->lock, flags); - return count; -} - -static ssize_t ata_scsi_lpm_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) - return -EINVAL; - - return snprintf(buf, PAGE_SIZE, "%s\n", - ata_lpm_policy_names[ap->target_lpm_policy]); -} -DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, - ata_scsi_lpm_show, ata_scsi_lpm_store); -EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); - static ssize_t ata_scsi_park_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -254,83 +187,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ata_scsi_park_show, ata_scsi_park_store); EXPORT_SYMBOL_GPL(dev_attr_unload_heads); -static ssize_t ata_ncq_prio_enable_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct scsi_device *sdev = to_scsi_device(device); - struct ata_port *ap; - struct ata_device *dev; - bool ncq_prio_enable; - int rc = 0; - - ap = ata_shost_to_port(sdev->host); - - spin_lock_irq(ap->lock); - dev = ata_scsi_find_dev(ap, sdev); - if (!dev) { - rc = -ENODEV; - goto unlock; - } - - ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; - -unlock: - spin_unlock_irq(ap->lock); - - return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); -} - -static ssize_t ata_ncq_prio_enable_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct scsi_device *sdev = to_scsi_device(device); - struct ata_port *ap; - struct ata_device *dev; - long int input; - int rc; - - rc = kstrtol(buf, 10, &input); - if (rc) - return rc; - if ((input < 0) || (input > 1)) - return -EINVAL; - - ap = ata_shost_to_port(sdev->host); - dev = ata_scsi_find_dev(ap, sdev); - if (unlikely(!dev)) - return -ENODEV; - - spin_lock_irq(ap->lock); - if (input) - dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; - else - dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; - - dev->link->eh_info.action |= ATA_EH_REVALIDATE; - dev->link->eh_info.flags |= ATA_EHI_QUIET; - ata_port_schedule_eh(ap); - spin_unlock_irq(ap->lock); - - ata_port_wait_eh(ap); - - if (input) { - spin_lock_irq(ap->lock); - if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; - rc = -EIO; - } - spin_unlock_irq(ap->lock); - } - - return rc ? rc : len; -} - -DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, - ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); -EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); - void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) { @@ -379,100 +235,12 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, field, 0xff, 0); } -static ssize_t -ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_store(ap, buf, count); - return -EINVAL; -} - -static ssize_t -ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_show(ap, buf); - return -EINVAL; -} -DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, - ata_scsi_em_message_show, ata_scsi_em_message_store); -EXPORT_SYMBOL_GPL(dev_attr_em_message); - -static ssize_t -ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - return snprintf(buf, 23, "%d\n", ap->em_message_type); -} -DEVICE_ATTR(em_message_type, S_IRUGO, - ata_scsi_em_message_type_show, NULL); -EXPORT_SYMBOL_GPL(dev_attr_em_message_type); - -static ssize_t -ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - - if (atadev && ap->ops->sw_activity_show && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) - return ap->ops->sw_activity_show(atadev, buf); - return -EINVAL; -} - -static ssize_t -ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - enum sw_activity val; - int rc; - - if (atadev && ap->ops->sw_activity_store && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) { - val = simple_strtoul(buf, NULL, 0); - switch (val) { - case OFF: case BLINK_ON: case BLINK_OFF: - rc = ap->ops->sw_activity_store(atadev, val); - if (!rc) - return count; - else - return rc; - } - } - return -EINVAL; -} -DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, - ata_scsi_activity_store); -EXPORT_SYMBOL_GPL(dev_attr_sw_activity); - struct device_attribute *ata_common_sdev_attrs[] = { &dev_attr_unload_heads, NULL }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -struct device_attribute *ata_ncq_sdev_attrs[] = { - &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, - NULL -}; -EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); - /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined @@ -1390,73 +1158,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) } EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); -/** - * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth - * @ap: ATA port to which the device change the queue depth - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * libsas and libata have different approaches for associating a sdev to - * its ata_port. - * - */ -int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth) -{ - struct ata_device *dev; - unsigned long flags; - - if (queue_depth < 1 || queue_depth == sdev->queue_depth) - return sdev->queue_depth; - - dev = ata_scsi_find_dev(ap, sdev); - if (!dev || !ata_dev_enabled(dev)) - return sdev->queue_depth; - - /* NCQ enabled? */ - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - if (queue_depth == 1 || !ata_ncq_enabled(dev)) { - dev->flags |= ATA_DFLAG_NCQ_OFF; - queue_depth = 1; - } - spin_unlock_irqrestore(ap->lock, flags); - - /* limit and apply queue depth */ - queue_depth = min(queue_depth, sdev->host->can_queue); - queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); - queue_depth = min(queue_depth, ATA_MAX_QUEUE); - - if (sdev->queue_depth == queue_depth) - return -EINVAL; - - return scsi_change_queue_depth(sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(__ata_change_queue_depth); - -/** - * ata_scsi_change_queue_depth - SCSI callback for queue depth config - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * This is libata standard hostt->change_queue_depth callback. - * SCSI will call into this callback when user tries to set queue - * depth via sysfs. - * - * LOCKING: - * SCSI layer (we don't care) - * - * RETURNS: - * Newly configured queue depth. - */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) -{ - struct ata_port *ap = ata_shost_to_port(sdev->host); - - return __ata_change_queue_depth(ap, sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); - /** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * @qc: Storage for translated ATA taskfile @@ -3093,7 +2794,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, * RETURNS: * Associated ATA device, or %NULL if not found. */ -static struct ata_device * +struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) { struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 8f5da7be88fe..2c479e48c4c9 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -153,6 +153,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} #endif /* libata-scsi.c */ +extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap, + const struct scsi_device *scsidev); extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); diff --git a/include/linux/libata.h b/include/linux/libata.h index 3124cad39d50..4b6ac3eda0c9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -532,12 +532,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes, unsigned long deadline); typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); -extern struct device_attribute dev_attr_link_power_management_policy; extern struct device_attribute dev_attr_unload_heads; +#ifdef CONFIG_SATA_HOST +extern struct device_attribute dev_attr_link_power_management_policy; extern struct device_attribute dev_attr_ncq_prio_enable; extern struct device_attribute dev_attr_em_message_type; extern struct device_attribute dev_attr_em_message; extern struct device_attribute dev_attr_sw_activity; +#endif enum sw_activity { OFF, @@ -1374,7 +1376,6 @@ extern int ata_link_nr_enabled(struct ata_link *link); extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; extern struct device_attribute *ata_common_sdev_attrs[]; -extern struct device_attribute *ata_ncq_sdev_attrs[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1399,10 +1400,14 @@ extern struct device_attribute *ata_ncq_sdev_attrs[]; .unlock_native_capacity = ata_scsi_unlock_native_capacity, \ .sdev_attrs = ata_common_sdev_attrs +#ifdef CONFIG_SATA_HOST +extern struct device_attribute *ata_ncq_sdev_attrs[]; + #define ATA_NCQ_SHT(drv_name) \ ATA_BASE_SHT(drv_name), \ .sdev_attrs = ata_ncq_sdev_attrs, \ .change_queue_depth = ata_scsi_change_queue_depth +#endif /* * PMP helpers -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c 2020-01-28 13:33 ` [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c Bartlomiej Zolnierkiewicz 2020-01-29 11:13 ` Bartlomiej Zolnierkiewicz @ 2020-01-29 17:31 ` Christoph Hellwig 2020-01-29 17:46 ` Martin K. Petersen 1 sibling, 1 reply; 54+ messages in thread From: Christoph Hellwig @ 2020-01-29 17:31 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On Tue, Jan 28, 2020 at 02:33:39PM +0100, Bartlomiej Zolnierkiewicz wrote: > * include libata-scsi-sata.c in the build when CONFIG_SATA_HOST=y The libata-core.c vs libata-scsi.c split already is a bit weird, any reason not to simply have a single libata-sata.c? ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c 2020-01-29 17:31 ` Christoph Hellwig @ 2020-01-29 17:46 ` Martin K. Petersen 2020-02-07 14:25 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 54+ messages in thread From: Martin K. Petersen @ 2020-01-29 17:46 UTC (permalink / raw) To: Christoph Hellwig Cc: Bartlomiej Zolnierkiewicz, Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel Christoph, > On Tue, Jan 28, 2020 at 02:33:39PM +0100, Bartlomiej Zolnierkiewicz wrote: >> * include libata-scsi-sata.c in the build when CONFIG_SATA_HOST=y > > The libata-core.c vs libata-scsi.c split already is a bit weird, any > reason not to simply have a single libata-sata.c? I agree, I also tripped over libata-scsi-sata. -- Martin K. Petersen Oracle Linux Engineering ^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c 2020-01-29 17:46 ` Martin K. Petersen @ 2020-02-07 14:25 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-02-07 14:25 UTC (permalink / raw) To: Martin K. Petersen, Christoph Hellwig Cc: Jens Axboe, Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel On 1/29/20 6:46 PM, Martin K. Petersen wrote: > > Christoph, > >> On Tue, Jan 28, 2020 at 02:33:39PM +0100, Bartlomiej Zolnierkiewicz wrote: >>> * include libata-scsi-sata.c in the build when CONFIG_SATA_HOST=y >> >> The libata-core.c vs libata-scsi.c split already is a bit weird, any >> reason not to simply have a single libata-sata.c? > > I agree, I also tripped over libata-scsi-sata. Fixed in v2 version of the patchset. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ^ permalink raw reply [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133419eucas1p14f7ed619db42aba72e83b7814f45a3bc@eucas1p1.samsung.com>]
* [PATCH 25/28] ata: move ata_sas_*() to libata-scsi-sata.c [not found] ` <CGME20200128133419eucas1p14f7ed619db42aba72e83b7814f45a3bc@eucas1p1.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * un-inline: - ata_scsi_dump_cdb() - __ata_scsi_queuecmd() * un-static: - ata_scsi_sdev_config() - ata_scsi_dev_config() - ata_scsi_dump_cdb() - __ata_scsi_queuecmd() * move ata_sas_*() to libata-scsi-sata.c: * add static inlines for CONFIG_SATA_HOST=n case for ata_sas_{allocate,free}_tag() Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 19137 23 4096 23256 5ad8 drivers/ata/libata-scsi.o after: 18330 23 4096 22449 57b1 drivers/ata/libata-scsi.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-scsi-sata.c | 213 +++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 222 +-------------------------------- drivers/ata/libata.h | 13 ++ include/linux/libata.h | 24 ++-- 4 files changed, 242 insertions(+), 230 deletions(-) diff --git a/drivers/ata/libata-scsi-sata.c b/drivers/ata/libata-scsi-sata.c index da7d8344d003..bc60841c4045 100644 --- a/drivers/ata/libata-scsi-sata.c +++ b/drivers/ata/libata-scsi-sata.c @@ -7,10 +7,12 @@ */ #include <linux/kernel.h> +#include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> #include <linux/libata.h> #include "libata.h" +#include "libata-transport.h" static const char *ata_lpm_policy_names[] = { [ATA_LPM_UNKNOWN] = "max_performance", @@ -308,3 +310,214 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) return __ata_change_queue_depth(ap, sdev, queue_depth); } EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); + +/** + * port_alloc - Allocate port for a SAS attached SATA device + * @host: ATA host container for all SAS ports + * @port_info: Information from low-level host driver + * @shost: SCSI host that the scsi device is attached to + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * ata_port pointer on success / NULL on failure. + */ + +struct ata_port *ata_sas_port_alloc(struct ata_host *host, + struct ata_port_info *port_info, + struct Scsi_Host *shost) +{ + struct ata_port *ap; + + ap = ata_port_alloc(host); + if (!ap) + return NULL; + + ap->port_no = 0; + ap->lock = &host->lock; + ap->pio_mask = port_info->pio_mask; + ap->mwdma_mask = port_info->mwdma_mask; + ap->udma_mask = port_info->udma_mask; + ap->flags |= port_info->flags; + ap->ops = port_info->port_ops; + ap->cbl = ATA_CBL_SATA; + + return ap; +} +EXPORT_SYMBOL_GPL(ata_sas_port_alloc); + +/** + * ata_sas_port_start - Set port up for dma. + * @ap: Port to initialize + * + * Called just after data structures for each port are + * initialized. + * + * May be used as the port_start() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +int ata_sas_port_start(struct ata_port *ap) +{ + /* + * the port is marked as frozen at allocation time, but if we don't + * have new eh, we won't thaw it + */ + if (!ap->ops->error_handler) + ap->pflags &= ~ATA_PFLAG_FROZEN; + return 0; +} +EXPORT_SYMBOL_GPL(ata_sas_port_start); + +/** + * ata_port_stop - Undo ata_sas_port_start() + * @ap: Port to shut down + * + * May be used as the port_stop() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ + +void ata_sas_port_stop(struct ata_port *ap) +{ +} +EXPORT_SYMBOL_GPL(ata_sas_port_stop); + +/** + * ata_sas_async_probe - simply schedule probing and return + * @ap: Port to probe + * + * For batch scheduling of probe for sas attached ata devices, assumes + * the port has already been through ata_sas_port_init() + */ +void ata_sas_async_probe(struct ata_port *ap) +{ + __ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_async_probe); + +int ata_sas_sync_probe(struct ata_port *ap) +{ + return ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_sync_probe); + + +/** + * ata_sas_port_init - Initialize a SATA device + * @ap: SATA port to initialize + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * Zero on success, non-zero on error. + */ + +int ata_sas_port_init(struct ata_port *ap) +{ + int rc = ap->ops->port_start(ap); + + if (rc) + return rc; + ap->print_id = atomic_inc_return(&ata_print_id); + return 0; +} +EXPORT_SYMBOL_GPL(ata_sas_port_init); + +int ata_sas_tport_add(struct device *parent, struct ata_port *ap) +{ + return ata_tport_add(parent, ap); +} +EXPORT_SYMBOL_GPL(ata_sas_tport_add); + +void ata_sas_tport_delete(struct ata_port *ap) +{ + ata_tport_delete(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_tport_delete); + +/** + * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc + * @ap: SATA port to destroy + * + */ + +void ata_sas_port_destroy(struct ata_port *ap) +{ + if (ap->ops->port_stop) + ap->ops->port_stop(ap); + kfree(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_port_destroy); + +/** + * ata_sas_slave_configure - Default slave_config routine for libata devices + * @sdev: SCSI device to configure + * @ap: ATA port to which SCSI device is attached + * + * RETURNS: + * Zero. + */ + +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; +} +EXPORT_SYMBOL_GPL(ata_sas_slave_configure); + +/** + * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device + * @cmd: SCSI command to be sent + * @ap: ATA port to which the command is being sent + * + * RETURNS: + * Return value from __ata_scsi_queuecmd() if @cmd can be queued, + * 0 otherwise. + */ + +int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) +{ + int rc = 0; + + ata_scsi_dump_cdb(ap, cmd); + + if (likely(ata_dev_enabled(ap->link.device))) + rc = __ata_scsi_queuecmd(cmd, ap->link.device); + else { + cmd->result = (DID_BAD_TARGET << 16); + cmd->scsi_done(cmd); + } + return rc; +} +EXPORT_SYMBOL_GPL(ata_sas_queuecmd); + +int ata_sas_allocate_tag(struct ata_port *ap) +{ + unsigned int max_queue = ap->host->n_tags; + unsigned int i, tag; + + for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { + tag = tag < max_queue ? tag : 0; + + /* the last tag is reserved for internal command. */ + if (ata_tag_internal(tag)) + continue; + + if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { + ap->sas_last_tag = tag; + return tag; + } + } + return -1; +} + +void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) +{ + clear_bit(tag, &ap->sas_tag_allocated); +} diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 82c398c93379..50a929adcbd6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -987,7 +987,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block); } -static void ata_scsi_sdev_config(struct scsi_device *sdev) +void ata_scsi_sdev_config(struct scsi_device *sdev) { sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; @@ -1027,8 +1027,7 @@ static int atapi_drain_needed(struct request *rq) return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC; } -static int ata_scsi_dev_config(struct scsi_device *sdev, - struct ata_device *dev) +int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) { struct request_queue *q = sdev->request_queue; @@ -4004,8 +4003,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) * Prints the contents of a SCSI command via printk(). */ -static inline void ata_scsi_dump_cdb(struct ata_port *ap, - struct scsi_cmnd *cmd) +void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd) { #ifdef ATA_VERBOSE_DEBUG struct scsi_device *scsidev = cmd->device; @@ -4017,8 +4015,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, #endif } -static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, - struct ata_device *dev) +int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) { u8 scsi_op = scmd->cmnd[0]; ata_xlat_func_t xlat_func; @@ -4635,214 +4632,3 @@ void ata_scsi_dev_rescan(struct work_struct *work) spin_unlock_irqrestore(ap->lock, flags); mutex_unlock(&ap->scsi_scan_mutex); } - -/** - * ata_sas_port_alloc - Allocate port for a SAS attached SATA device - * @host: ATA host container for all SAS ports - * @port_info: Information from low-level host driver - * @shost: SCSI host that the scsi device is attached to - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * ata_port pointer on success / NULL on failure. - */ - -struct ata_port *ata_sas_port_alloc(struct ata_host *host, - struct ata_port_info *port_info, - struct Scsi_Host *shost) -{ - struct ata_port *ap; - - ap = ata_port_alloc(host); - if (!ap) - return NULL; - - ap->port_no = 0; - ap->lock = &host->lock; - ap->pio_mask = port_info->pio_mask; - ap->mwdma_mask = port_info->mwdma_mask; - ap->udma_mask = port_info->udma_mask; - ap->flags |= port_info->flags; - ap->ops = port_info->port_ops; - ap->cbl = ATA_CBL_SATA; - - return ap; -} -EXPORT_SYMBOL_GPL(ata_sas_port_alloc); - -/** - * ata_sas_port_start - Set port up for dma. - * @ap: Port to initialize - * - * Called just after data structures for each port are - * initialized. - * - * May be used as the port_start() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -int ata_sas_port_start(struct ata_port *ap) -{ - /* - * the port is marked as frozen at allocation time, but if we don't - * have new eh, we won't thaw it - */ - if (!ap->ops->error_handler) - ap->pflags &= ~ATA_PFLAG_FROZEN; - return 0; -} -EXPORT_SYMBOL_GPL(ata_sas_port_start); - -/** - * ata_port_stop - Undo ata_sas_port_start() - * @ap: Port to shut down - * - * May be used as the port_stop() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ - -void ata_sas_port_stop(struct ata_port *ap) -{ -} -EXPORT_SYMBOL_GPL(ata_sas_port_stop); - -/** - * ata_sas_async_probe - simply schedule probing and return - * @ap: Port to probe - * - * For batch scheduling of probe for sas attached ata devices, assumes - * the port has already been through ata_sas_port_init() - */ -void ata_sas_async_probe(struct ata_port *ap) -{ - __ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_async_probe); - -int ata_sas_sync_probe(struct ata_port *ap) -{ - return ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_sync_probe); - - -/** - * ata_sas_port_init - Initialize a SATA device - * @ap: SATA port to initialize - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * Zero on success, non-zero on error. - */ - -int ata_sas_port_init(struct ata_port *ap) -{ - int rc = ap->ops->port_start(ap); - - if (rc) - return rc; - ap->print_id = atomic_inc_return(&ata_print_id); - return 0; -} -EXPORT_SYMBOL_GPL(ata_sas_port_init); - -int ata_sas_tport_add(struct device *parent, struct ata_port *ap) -{ - return ata_tport_add(parent, ap); -} -EXPORT_SYMBOL_GPL(ata_sas_tport_add); - -void ata_sas_tport_delete(struct ata_port *ap) -{ - ata_tport_delete(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_tport_delete); - -/** - * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc - * @ap: SATA port to destroy - * - */ - -void ata_sas_port_destroy(struct ata_port *ap) -{ - if (ap->ops->port_stop) - ap->ops->port_stop(ap); - kfree(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_port_destroy); - -/** - * ata_sas_slave_configure - Default slave_config routine for libata devices - * @sdev: SCSI device to configure - * @ap: ATA port to which SCSI device is attached - * - * RETURNS: - * Zero. - */ - -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; -} -EXPORT_SYMBOL_GPL(ata_sas_slave_configure); - -/** - * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device - * @cmd: SCSI command to be sent - * @ap: ATA port to which the command is being sent - * - * RETURNS: - * Return value from __ata_scsi_queuecmd() if @cmd can be queued, - * 0 otherwise. - */ - -int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) -{ - int rc = 0; - - ata_scsi_dump_cdb(ap, cmd); - - if (likely(ata_dev_enabled(ap->link.device))) - rc = __ata_scsi_queuecmd(cmd, ap->link.device); - else { - cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); - } - return rc; -} -EXPORT_SYMBOL_GPL(ata_sas_queuecmd); - -int ata_sas_allocate_tag(struct ata_port *ap) -{ - unsigned int max_queue = ap->host->n_tags; - unsigned int i, tag; - - for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { - tag = tag < max_queue ? tag : 0; - - /* the last tag is reserved for internal command. */ - if (ata_tag_internal(tag)) - continue; - - if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { - ap->sas_last_tag = tag; - return tag; - } - } - return -1; -} - -void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) -{ - clear_bit(tag, &ap->sas_tag_allocated); -} diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2c479e48c4c9..2bb87a3e7a62 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -171,8 +171,21 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); extern int ata_bus_probe(struct ata_port *ap); extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, unsigned int id, u64 lun); +void ata_scsi_sdev_config(struct scsi_device *sdev); +int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev); +void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd); +int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev); +/* libata-scsi-sata.c */ +#ifdef CONFIG_SATA_HOST int ata_sas_allocate_tag(struct ata_port *ap); void ata_sas_free_tag(unsigned int tag, struct ata_port *ap); +#else +static inline int ata_sas_allocate_tag(struct ata_port *ap) +{ + return -EOPNOTSUPP; +} +static inline void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) { } +#endif /* libata-eh.c */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 4b6ac3eda0c9..eb2797c27547 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1096,18 +1096,6 @@ extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd, extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd); extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, unsigned int cmd, void __user *arg); -extern void ata_sas_port_destroy(struct ata_port *); -extern struct ata_port *ata_sas_port_alloc(struct ata_host *, - struct ata_port_info *, struct Scsi_Host *); -extern void ata_sas_async_probe(struct ata_port *ap); -extern int ata_sas_sync_probe(struct ata_port *ap); -extern int ata_sas_port_init(struct ata_port *); -extern int ata_sas_port_start(struct ata_port *ap); -extern int ata_sas_tport_add(struct device *parent, struct ata_port *ap); -extern void ata_sas_tport_delete(struct ata_port *ap); -extern void ata_sas_port_stop(struct ata_port *ap); -extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); -extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); extern bool ata_link_online(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM @@ -1196,6 +1184,18 @@ extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); extern int ata_slave_link_init(struct ata_port *ap); +extern void ata_sas_port_destroy(struct ata_port *); +extern struct ata_port *ata_sas_port_alloc(struct ata_host *, + struct ata_port_info *, struct Scsi_Host *); +extern void ata_sas_async_probe(struct ata_port *ap); +extern int ata_sas_sync_probe(struct ata_port *ap); +extern int ata_sas_port_init(struct ata_port *); +extern int ata_sas_port_start(struct ata_port *ap); +extern int ata_sas_tport_add(struct device *parent, struct ata_port *ap); +extern void ata_sas_tport_delete(struct ata_port *ap); +extern void ata_sas_port_stop(struct ata_port *ap); +extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); +extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); extern int sata_scr_valid(struct ata_link *link); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val); -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133419eucas1p293e7f2e62e74c9208a30fd83650e8615@eucas1p2.samsung.com>]
* [PATCH 26/28] ata: start separating SATA specific code from libata-eh.c [not found] ` <CGME20200128133419eucas1p293e7f2e62e74c9208a30fd83650e8615@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie 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@samsung.com> --- 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@gmail.com> + */ + +#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 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133420eucas1p294e2d41ec0eb0457ff781c69a5bcc489@eucas1p2.samsung.com>]
* [PATCH 27/28] ata: move ata_eh_analyze_ncq_error() & co. to libata-core-sata.c [not found] ` <CGME20200128133420eucas1p294e2d41ec0eb0457ff781c69a5bcc489@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * move ata_eh_analyze_ncq_error() and ata_eh_read_log_10h() to libata-eh-sata.c * add static inline for ata_eh_analyze_ncq_error() for CONFIG_SATA_HOST=n case (link->sactive is non-zero only if NCQ commands are actually queued so empty function body is sufficient) Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 16810 18 0 16828 41bc drivers/ata/libata-eh.o after: 16092 18 0 16110 3eee drivers/ata/libata-eh.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-eh-sata.c | 131 +++++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 131 ----------------------------------- include/linux/libata.h | 4 +- 3 files changed, 134 insertions(+), 132 deletions(-) diff --git a/drivers/ata/libata-eh-sata.c b/drivers/ata/libata-eh-sata.c index 4b6dc715629a..4b55d89862fb 100644 --- a/drivers/ata/libata-eh-sata.c +++ b/drivers/ata/libata-eh-sata.c @@ -83,3 +83,134 @@ int sata_async_notification(struct ata_port *ap) } } EXPORT_SYMBOL_GPL(sata_async_notification); + +/** + * ata_eh_read_log_10h - Read log page 10h for NCQ error details + * @dev: Device to read log page 10h from + * @tag: Resulting tag of the failed command + * @tf: Resulting taskfile registers of the failed command + * + * Read log page 10h to obtain NCQ error details and clear error + * condition. + * + * LOCKING: + * Kernel thread context (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +static int ata_eh_read_log_10h(struct ata_device *dev, + int *tag, struct ata_taskfile *tf) +{ + u8 *buf = dev->link->ap->sector_buf; + unsigned int err_mask; + u8 csum; + int i; + + err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); + if (err_mask) + return -EIO; + + csum = 0; + for (i = 0; i < ATA_SECT_SIZE; i++) + csum += buf[i]; + if (csum) + ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", + csum); + + if (buf[0] & 0x80) + return -ENOENT; + + *tag = buf[0] & 0x1f; + + tf->command = buf[2]; + tf->feature = buf[3]; + tf->lbal = buf[4]; + tf->lbam = buf[5]; + tf->lbah = buf[6]; + tf->device = buf[7]; + tf->hob_lbal = buf[8]; + tf->hob_lbam = buf[9]; + tf->hob_lbah = buf[10]; + tf->nsect = buf[12]; + tf->hob_nsect = buf[13]; + if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; + + return 0; +} + +/** + * ata_eh_analyze_ncq_error - analyze NCQ error + * @link: ATA link to analyze NCQ error for + * + * Read log page 10h, determine the offending qc and acquire + * error status TF. For NCQ device errors, all LLDDs have to do + * is setting AC_ERR_DEV in ehi->err_mask. This function takes + * care of the rest. + * + * LOCKING: + * Kernel thread context (may sleep). + */ +void ata_eh_analyze_ncq_error(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + struct ata_eh_context *ehc = &link->eh_context; + struct ata_device *dev = link->device; + struct ata_queued_cmd *qc; + struct ata_taskfile tf; + int tag, rc; + + /* if frozen, we can't do much */ + if (ap->pflags & ATA_PFLAG_FROZEN) + return; + + /* is it NCQ device error? */ + if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) + return; + + /* has LLDD analyzed already? */ + ata_qc_for_each_raw(ap, qc, tag) { + if (!(qc->flags & ATA_QCFLAG_FAILED)) + continue; + + if (qc->err_mask) + return; + } + + /* okay, this error is ours */ + memset(&tf, 0, sizeof(tf)); + rc = ata_eh_read_log_10h(dev, &tag, &tf); + if (rc) { + ata_link_err(link, "failed to read log page 10h (errno=%d)\n", + rc); + return; + } + + if (!(link->sactive & (1 << tag))) { + ata_link_err(link, "log page 10h reported inactive tag %d\n", + tag); + return; + } + + /* we've got the perpetrator, condemn it */ + qc = __ata_qc_from_tag(ap, tag); + memcpy(&qc->result_tf, &tf, sizeof(tf)); + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; + qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; + if (dev->class == ATA_DEV_ZAC && + ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { + char sense_key, asc, ascq; + + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; + asc = (qc->result_tf.auxiliary >> 8) & 0xff; + ascq = qc->result_tf.auxiliary & 0xff; + ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); + ata_scsi_set_sense_information(dev, qc->scsicmd, + &qc->result_tf); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + } + + ehc->i.err_mask &= ~AC_ERR_DEV; +} +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 201165955b90..b37e93c5013d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1351,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask) return "unknown error"; } -/** - * ata_eh_read_log_10h - Read log page 10h for NCQ error details - * @dev: Device to read log page 10h from - * @tag: Resulting tag of the failed command - * @tf: Resulting taskfile registers of the failed command - * - * Read log page 10h to obtain NCQ error details and clear error - * condition. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int ata_eh_read_log_10h(struct ata_device *dev, - int *tag, struct ata_taskfile *tf) -{ - u8 *buf = dev->link->ap->sector_buf; - unsigned int err_mask; - u8 csum; - int i; - - err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); - if (err_mask) - return -EIO; - - csum = 0; - for (i = 0; i < ATA_SECT_SIZE; i++) - csum += buf[i]; - if (csum) - ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", - csum); - - if (buf[0] & 0x80) - return -ENOENT; - - *tag = buf[0] & 0x1f; - - tf->command = buf[2]; - tf->feature = buf[3]; - tf->lbal = buf[4]; - tf->lbam = buf[5]; - tf->lbah = buf[6]; - tf->device = buf[7]; - tf->hob_lbal = buf[8]; - tf->hob_lbam = buf[9]; - tf->hob_lbah = buf[10]; - tf->nsect = buf[12]; - tf->hob_nsect = buf[13]; - if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) - tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; - - return 0; -} - /** * atapi_eh_tur - perform ATAPI TEST_UNIT_READY * @dev: target ATAPI device @@ -1590,81 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link) ehc->i.action |= action; } -/** - * ata_eh_analyze_ncq_error - analyze NCQ error - * @link: ATA link to analyze NCQ error for - * - * Read log page 10h, determine the offending qc and acquire - * error status TF. For NCQ device errors, all LLDDs have to do - * is setting AC_ERR_DEV in ehi->err_mask. This function takes - * care of the rest. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_eh_analyze_ncq_error(struct ata_link *link) -{ - struct ata_port *ap = link->ap; - struct ata_eh_context *ehc = &link->eh_context; - struct ata_device *dev = link->device; - struct ata_queued_cmd *qc; - struct ata_taskfile tf; - int tag, rc; - - /* if frozen, we can't do much */ - if (ap->pflags & ATA_PFLAG_FROZEN) - return; - - /* is it NCQ device error? */ - if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) - return; - - /* has LLDD analyzed already? */ - ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - - if (qc->err_mask) - return; - } - - /* okay, this error is ours */ - memset(&tf, 0, sizeof(tf)); - rc = ata_eh_read_log_10h(dev, &tag, &tf); - if (rc) { - ata_link_err(link, "failed to read log page 10h (errno=%d)\n", - rc); - return; - } - - if (!(link->sactive & (1 << tag))) { - ata_link_err(link, "log page 10h reported inactive tag %d\n", - tag); - return; - } - - /* we've got the perpetrator, condemn it */ - qc = __ata_qc_from_tag(ap, tag); - memcpy(&qc->result_tf, &tf, sizeof(tf)); - qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; - if (dev->class == ATA_DEV_ZAC && - ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { - char sense_key, asc, ascq; - - sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; - asc = (qc->result_tf.auxiliary >> 8) & 0xff; - ascq = qc->result_tf.auxiliary & 0xff; - ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); - ata_scsi_set_sense_information(dev, qc->scsicmd, - &qc->result_tf); - qc->flags |= ATA_QCFLAG_SENSE_VALID; - } - - ehc->i.err_mask &= ~AC_ERR_DEV; -} -EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); - /** * ata_eh_analyze_tf - analyze taskfile of a failed qc * @qc: qc to analyze diff --git a/include/linux/libata.h b/include/linux/libata.h index d09997e2290b..aba4bebb25f1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1341,7 +1341,6 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_eh_analyze_ncq_error(struct ata_link *link); extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, @@ -1356,6 +1355,9 @@ extern int ata_link_nr_enabled(struct ata_link *link); */ #ifdef CONFIG_SATA_HOST extern int sata_async_notification(struct ata_port *ap); +extern void ata_eh_analyze_ncq_error(struct ata_link *link); +#else +static inline void ata_eh_analyze_ncq_error(struct ata_link *link) { } #endif /* -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
[parent not found: <CGME20200128133420eucas1p23e99a72e7735412f93dc015b8cb25d4b@eucas1p2.samsung.com>]
* [PATCH 28/28] ata: move ata_eh_set_lpm() to libata-core-sata.c [not found] ` <CGME20200128133420eucas1p23e99a72e7735412f93dc015b8cb25d4b@eucas1p2.samsung.com> @ 2020-01-28 13:33 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 54+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2020-01-28 13:33 UTC (permalink / raw) To: Jens Axboe Cc: Michael Schmitz, Geert Uytterhoeven, linux-ide, linux-kernel, b.zolnierkie * un-static ata_eh_set_lpm() and move it to libata-eh-sata.c * add static inline for ata_eh_set_lpm() for CONFIG_SATA_HOST=n case (for PATA hosts "ap && !ap->ops->set_lpm" condition is always true so it's sufficient for the function to return zero) Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 16092 18 0 16110 3eee drivers/ata/libata-eh.o after: 15346 18 0 15364 3c04 drivers/ata/libata-eh.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/ata/libata-eh-sata.c | 133 +++++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 133 ----------------------------------- drivers/ata/libata.h | 9 +++ 3 files changed, 142 insertions(+), 133 deletions(-) diff --git a/drivers/ata/libata-eh-sata.c b/drivers/ata/libata-eh-sata.c index 4b55d89862fb..cd7b1b434d53 100644 --- a/drivers/ata/libata-eh-sata.c +++ b/drivers/ata/libata-eh-sata.c @@ -214,3 +214,136 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ehc->i.err_mask &= ~AC_ERR_DEV; } EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); + +/** + * ata_eh_set_lpm - configure SATA interface power management + * @link: link to configure power management + * @policy: the link power management policy + * @r_failed_dev: out parameter for failed device + * + * Enable SATA Interface power management. This will enable + * Device Interface Power Management (DIPM) for min_power and + * medium_power_with_dipm policies, and then call driver specific + * callbacks for enabling Host Initiated Power management. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + struct ata_device **r_failed_dev) +{ + struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; + struct ata_eh_context *ehc = &link->eh_context; + struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; + enum ata_lpm_policy old_policy = link->lpm_policy; + bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM; + unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; + unsigned int err_mask; + int rc; + + /* if the link or host doesn't do LPM, noop */ + if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) + return 0; + + /* + * DIPM is enabled only for MIN_POWER as some devices + * misbehave when the host NACKs transition to SLUMBER. Order + * device and link configurations such that the host always + * allows DIPM requests. + */ + ata_for_each_dev(dev, link, ENABLED) { + bool hipm = ata_id_has_hipm(dev->id); + bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; + + /* find the first enabled and LPM enabled devices */ + if (!link_dev) + link_dev = dev; + + if (!lpm_dev && (hipm || dipm)) + lpm_dev = dev; + + hints &= ~ATA_LPM_EMPTY; + if (!hipm) + hints &= ~ATA_LPM_HIPM; + + /* disable DIPM before changing link config */ + if (policy < ATA_LPM_MED_POWER_WITH_DIPM && dipm) { + err_mask = ata_dev_set_feature(dev, + SETFEATURES_SATA_DISABLE, SATA_DIPM); + if (err_mask && err_mask != AC_ERR_DEV) { + ata_dev_warn(dev, + "failed to disable DIPM, Emask 0x%x\n", + err_mask); + rc = -EIO; + goto fail; + } + } + } + + if (ap) { + rc = ap->ops->set_lpm(link, policy, hints); + if (!rc && ap->slave_link) + rc = ap->ops->set_lpm(ap->slave_link, policy, hints); + } else + rc = sata_pmp_set_lpm(link, policy, hints); + + /* + * Attribute link config failure to the first (LPM) enabled + * device on the link. + */ + if (rc) { + if (rc == -EOPNOTSUPP) { + link->flags |= ATA_LFLAG_NO_LPM; + return 0; + } + dev = lpm_dev ? lpm_dev : link_dev; + goto fail; + } + + /* + * Low level driver acked the transition. Issue DIPM command + * with the new policy set. + */ + link->lpm_policy = policy; + if (ap && ap->slave_link) + ap->slave_link->lpm_policy = policy; + + /* host config updated, enable DIPM if transitioning to MIN_POWER */ + ata_for_each_dev(dev, link, ENABLED) { + if (policy >= ATA_LPM_MED_POWER_WITH_DIPM && !no_dipm && + ata_id_has_dipm(dev->id)) { + err_mask = ata_dev_set_feature(dev, + SETFEATURES_SATA_ENABLE, SATA_DIPM); + if (err_mask && err_mask != AC_ERR_DEV) { + ata_dev_warn(dev, + "failed to enable DIPM, Emask 0x%x\n", + err_mask); + rc = -EIO; + goto fail; + } + } + } + + link->last_lpm_change = jiffies; + link->flags |= ATA_LFLAG_CHANGED; + + return 0; + +fail: + /* restore the old policy */ + link->lpm_policy = old_policy; + if (ap && ap->slave_link) + ap->slave_link->lpm_policy = old_policy; + + /* if no device or only one more chance is left, disable LPM */ + if (!dev || ehc->tries[dev->devno] <= 2) { + ata_link_warn(link, "disabling LPM on the link\n"); + link->flags |= ATA_LFLAG_NO_LPM; + } + if (r_failed_dev) + *r_failed_dev = dev; + return rc; +} diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index b37e93c5013d..723645cefee9 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3208,139 +3208,6 @@ static int ata_eh_maybe_retry_flush(struct ata_device *dev) return rc; } -/** - * ata_eh_set_lpm - configure SATA interface power management - * @link: link to configure power management - * @policy: the link power management policy - * @r_failed_dev: out parameter for failed device - * - * Enable SATA Interface power management. This will enable - * Device Interface Power Management (DIPM) for min_power and - * medium_power_with_dipm policies, and then call driver specific - * callbacks for enabling Host Initiated Power management. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, - struct ata_device **r_failed_dev) -{ - struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; - struct ata_eh_context *ehc = &link->eh_context; - struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; - enum ata_lpm_policy old_policy = link->lpm_policy; - bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM; - unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; - unsigned int err_mask; - int rc; - - /* if the link or host doesn't do LPM, noop */ - if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) - return 0; - - /* - * DIPM is enabled only for MIN_POWER as some devices - * misbehave when the host NACKs transition to SLUMBER. Order - * device and link configurations such that the host always - * allows DIPM requests. - */ - ata_for_each_dev(dev, link, ENABLED) { - bool hipm = ata_id_has_hipm(dev->id); - bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; - - /* find the first enabled and LPM enabled devices */ - if (!link_dev) - link_dev = dev; - - if (!lpm_dev && (hipm || dipm)) - lpm_dev = dev; - - hints &= ~ATA_LPM_EMPTY; - if (!hipm) - hints &= ~ATA_LPM_HIPM; - - /* disable DIPM before changing link config */ - if (policy < ATA_LPM_MED_POWER_WITH_DIPM && dipm) { - err_mask = ata_dev_set_feature(dev, - SETFEATURES_SATA_DISABLE, SATA_DIPM); - if (err_mask && err_mask != AC_ERR_DEV) { - ata_dev_warn(dev, - "failed to disable DIPM, Emask 0x%x\n", - err_mask); - rc = -EIO; - goto fail; - } - } - } - - if (ap) { - rc = ap->ops->set_lpm(link, policy, hints); - if (!rc && ap->slave_link) - rc = ap->ops->set_lpm(ap->slave_link, policy, hints); - } else - rc = sata_pmp_set_lpm(link, policy, hints); - - /* - * Attribute link config failure to the first (LPM) enabled - * device on the link. - */ - if (rc) { - if (rc == -EOPNOTSUPP) { - link->flags |= ATA_LFLAG_NO_LPM; - return 0; - } - dev = lpm_dev ? lpm_dev : link_dev; - goto fail; - } - - /* - * Low level driver acked the transition. Issue DIPM command - * with the new policy set. - */ - link->lpm_policy = policy; - if (ap && ap->slave_link) - ap->slave_link->lpm_policy = policy; - - /* host config updated, enable DIPM if transitioning to MIN_POWER */ - ata_for_each_dev(dev, link, ENABLED) { - if (policy >= ATA_LPM_MED_POWER_WITH_DIPM && !no_dipm && - ata_id_has_dipm(dev->id)) { - err_mask = ata_dev_set_feature(dev, - SETFEATURES_SATA_ENABLE, SATA_DIPM); - if (err_mask && err_mask != AC_ERR_DEV) { - ata_dev_warn(dev, - "failed to enable DIPM, Emask 0x%x\n", - err_mask); - rc = -EIO; - goto fail; - } - } - } - - link->last_lpm_change = jiffies; - link->flags |= ATA_LFLAG_CHANGED; - - return 0; - -fail: - /* restore the old policy */ - link->lpm_policy = old_policy; - if (ap && ap->slave_link) - ap->slave_link->lpm_policy = old_policy; - - /* if no device or only one more chance is left, disable LPM */ - if (!dev || ehc->tries[dev->devno] <= 2) { - ata_link_warn(link, "disabling LPM on the link\n"); - link->flags |= ATA_LFLAG_NO_LPM; - } - if (r_failed_dev) - *r_failed_dev = dev; - return rc; -} - int ata_link_nr_enabled(struct ata_link *link) { struct ata_device *dev; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2bb87a3e7a62..5860ad5f348e 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -220,6 +220,15 @@ extern int ata_ering_map(struct ata_ering *ering, extern unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key); extern unsigned int atapi_eh_request_sense(struct ata_device *dev, u8 *sense_buf, u8 dfl_sense_key); +/* libata-eh-sata.c */ +#ifdef CONFIG_SATA_HOST +int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + struct ata_device **r_failed_dev); +#else +static inline int ata_eh_set_lpm(struct ata_link *link, + enum ata_lpm_policy policy, + struct ata_device **r_failed_dev) { return 0; } +#endif /* libata-pmp.c */ #ifdef CONFIG_SATA_PMP -- 2.24.1 ^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 00/28] ata: optimize core code size on PATA only setups 2020-01-28 13:33 ` [PATCH 00/28] ata: optimize core code size on PATA only setups Bartlomiej Zolnierkiewicz ` (27 preceding siblings ...) [not found] ` <CGME20200128133420eucas1p23e99a72e7735412f93dc015b8cb25d4b@eucas1p2.samsung.com> @ 2020-01-28 14:00 ` Geert Uytterhoeven 28 siblings, 0 replies; 54+ messages in thread From: Geert Uytterhoeven @ 2020-01-28 14:00 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: Jens Axboe, Michael Schmitz, linux-ide, Linux Kernel Mailing List, linux-m68k Hi Bartlomiej, CC linux-m68k On Tue, Jan 28, 2020 at 2:34 PM Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> wrote: > There have been reports in the past of libata core code size > being a problem in migration from deprecated IDE subsystem on > legacy PATA only systems, i.e.: > > https://lore.kernel.org/linux-ide/db2838b7-4862-785b-3a1d-3bf09811340a@gmail.com/ > > This patchset re-organizes libata core code to exclude SATA > specific code from being built for PATA only setups. > > The end result is up to 17% (by 17246 bytes, from 101787 bytes to > 84541 bytes) smaller libata core code size (as measured for m68k > arch using atari_defconfig) on affected setups. > > I've tested this patchset using pata_falcon driver under ARAnyM > emulator. Thanks a lot! [...] https://lore.kernel.org/lkml/20200128133343.29905-1-b.zolnierkie@samsung.com/ Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ^ permalink raw reply [flat|nested] 54+ messages in thread
end of thread, other threads:[~2020-02-07 14:25 UTC | newest] Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <CGME20200128133410eucas1p19fb97c9696596da07181e0c630fb6c6b@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 00/28] ata: optimize core code size on PATA only setups Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133410eucas1p271284329b9b63c2c48167308809c569c@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 01/28] ata: remove stale maintainership information from core code Bartlomiej Zolnierkiewicz 2020-01-28 14:28 ` Tejun Heo [not found] ` <CGME20200128133411eucas1p2db496c50fea321b621b1a07b4b8a8cc2@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 02/28] ata: expose ncq_enable_prio sysfs attribute only on NCQ capable hosts Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133411eucas1p1671c280eb6f5d2ca2d10743eea6c96e5@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 03/28] ata: make SATA_PMP option selectable only if any SATA host driver is enabled Bartlomiej Zolnierkiewicz 2020-01-29 2:35 ` Martin K. Petersen [not found] ` <CGME20200128133412eucas1p2c79626824fcadc63c133548cd2e7d8cf@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 04/28] sata_promise: use ata_cable_sata() Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133412eucas1p258499338146481964e4c26ad3f1cbf14@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 05/28] ata: simplify ata_scsiop_inq_89() Bartlomiej Zolnierkiewicz 2020-01-29 17:15 ` Christoph Hellwig [not found] ` <CGME20200128133412eucas1p2e5e3e29ea554bf57c1f2cc05b3d2d3a8@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 06/28] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig 2020-02-07 14:17 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133412eucas1p1b1b4f025e4c0e6ae6e7a95e9832880dd@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 07/28] ata: optimize struct ata_force_param size Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig [not found] ` <CGME20200128133413eucas1p195d291f69413cbb3bb86da9571942259@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 08/28] ata: move EXPORT_SYMBOL_GPL()s close to exported code Bartlomiej Zolnierkiewicz 2020-01-29 17:18 ` Christoph Hellwig [not found] ` <CGME20200128133413eucas1p1725ccae03fb5aba49f0e0cef798da9d6@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 09/28] ata: remove EXPORT_SYMBOL_GPL()s not used by modules Bartlomiej Zolnierkiewicz 2020-01-29 17:19 ` Christoph Hellwig [not found] ` <CGME20200128133414eucas1p14b041a2d58ca70817f3007c0f405ee73@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 10/28] ata: separate PATA timings code from libata-core.c Bartlomiej Zolnierkiewicz 2020-01-29 17:23 ` Christoph Hellwig 2020-02-07 14:20 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133414eucas1p1c69ee66d4799a5aea22561b42ab73e11@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 11/28] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() Bartlomiej Zolnierkiewicz 2020-01-29 17:24 ` Christoph Hellwig 2020-02-07 14:21 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133414eucas1p2baefeb1a492375b18bdf6cdfbd0db796@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 12/28] ata: start separating SATA specific code from libata-core.c Bartlomiej Zolnierkiewicz 2020-01-29 17:26 ` Christoph Hellwig 2020-02-07 14:22 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133415eucas1p258c0d5c313e2ae42a05508b67eec16ef@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 13/28] ata: move ata_do_link_spd_horkage() to libata-core-sata.c Bartlomiej Zolnierkiewicz 2020-01-29 17:28 ` Christoph Hellwig 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133415eucas1p1cd35ec3ee9783b76c1a32de63796ce30@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 14/28] ata: move ata_dev_config_ncq*() " Bartlomiej Zolnierkiewicz 2020-01-29 17:29 ` Christoph Hellwig 2020-02-07 14:23 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133415eucas1p12cc620dd5f19e6a26f1deeba083ea82f@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 15/28] ata: move sata_print_link_status() " Bartlomiej Zolnierkiewicz 2020-01-29 17:30 ` Christoph Hellwig 2020-02-07 14:24 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133416eucas1p1eb121384be2323aed1fc63a6d1ebe14f@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 16/28] ata: move sata_down_spd_limit() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133416eucas1p240f8fc15b334e0608cce30f2b6f0fbe1@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 17/28] ata: move *sata_set_spd*() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133416eucas1p172512260c12e8cce9516dd194c467134@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 18/28] ata: move sata_link_{debounce,resume}() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133417eucas1p1b907d220ad2b809cdf628fb47a14589c@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 19/28] ata: move sata_link_hardreset() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133417eucas1p28b1e3fbb20c686bd75997f5339993071@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 20/28] ata: move sata_link_init_spd() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133417eucas1p27f91558f4b86f6951d2f9f1ed19d84b5@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 21/28] ata: move ata_qc_complete_multiple() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133418eucas1p1b28eb901c4d21446376c1028b2977017@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 22/28] ata: move sata_scr_*() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133418eucas1p1fd63b12146a2848ab61db768fde77857@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 23/28] ata: move sata_deb_timing_*() " Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133418eucas1p157933935f14f9c83c604bc5dc38bcbae@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 24/28] ata: start separating SATA specific code from libata-scsi.c Bartlomiej Zolnierkiewicz 2020-01-29 11:13 ` Bartlomiej Zolnierkiewicz 2020-01-29 17:31 ` Christoph Hellwig 2020-01-29 17:46 ` Martin K. Petersen 2020-02-07 14:25 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133419eucas1p14f7ed619db42aba72e83b7814f45a3bc@eucas1p1.samsung.com> 2020-01-28 13:33 ` [PATCH 25/28] ata: move ata_sas_*() to libata-scsi-sata.c Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133419eucas1p293e7f2e62e74c9208a30fd83650e8615@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 26/28] ata: start separating SATA specific code from libata-eh.c Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133420eucas1p294e2d41ec0eb0457ff781c69a5bcc489@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 27/28] ata: move ata_eh_analyze_ncq_error() & co. to libata-core-sata.c Bartlomiej Zolnierkiewicz [not found] ` <CGME20200128133420eucas1p23e99a72e7735412f93dc015b8cb25d4b@eucas1p2.samsung.com> 2020-01-28 13:33 ` [PATCH 28/28] ata: move ata_eh_set_lpm() " Bartlomiej Zolnierkiewicz 2020-01-28 14:00 ` [PATCH 00/28] ata: optimize core code size on PATA only setups Geert Uytterhoeven
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).