Commit 3a0eb192 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.7/libata-2020-03-29' of git://git.kernel.dk/linux-block

Pull libata updates from Jens Axboe:

 - Series from Bart, making the libata code smaller on PATA only setups.
   This is useful for smaller/embedded use cases, and will help us move
   some of those off drivers/ide.

 - Kill unused BPRINTK() (Hannes)

 - Add various Comet Lake ahci PCI ids (Kai-Heng, Mika)

 - Fix for a double scsi_host_put() in error handling (John)

 - Use scnprintf (Takashi)

 - Assign OF node to the SCSI device (Linus Walleij)

* tag 'for-5.7/libata-2020-03-29' of git://git.kernel.dk/linux-block: (36 commits)
  ata: make "libata.force" kernel parameter optional
  ata: move ata_eh_analyze_ncq_error() & co. to libata-sata.c
  ata: start separating SATA specific code from libata-eh.c
  ata: move ata_sas_*() to libata-sata.c
  ata: start separating SATA specific code from libata-scsi.c
  ata: move sata_deb_timing_*() to libata-sata.c
  ata: move ata_qc_complete_multiple() to libata-sata.c
  ata: move sata_link_hardreset() to libata-sata.c
  ata: move sata_link_{debounce,resume}() to libata-sata.c
  ata: move *sata_set_spd*() to libata-sata.c
  ata: move sata_scr_*() to libata-sata.c
  ata: start separating SATA specific code from libata-core.c
  ata: let compiler optimize out ata_eh_set_lpm() on non-SATA hosts
  ata: let compiler optimize out ata_dev_config_ncq() on non-SATA hosts
  ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled()
  ata: separate PATA timings code from libata-core.c
  ata: fix CodingStyle issues in PATA timings code
  ata: remove EXPORT_SYMBOL_GPL()s not used by modules
  ata: move EXPORT_SYMBOL_GPL()s close to exported code
  ata: optimize ata_scsi_rbuf[] size
  ...
parents c03cb664 bf89b0bf
...@@ -34,6 +34,12 @@ if ATA ...@@ -34,6 +34,12 @@ if ATA
config ATA_NONSTANDARD config ATA_NONSTANDARD
bool bool
config SATA_HOST
bool
config PATA_TIMINGS
bool
config ATA_VERBOSE_ERROR config ATA_VERBOSE_ERROR
bool "Verbose ATA error reporting" bool "Verbose ATA error reporting"
default y default y
...@@ -45,9 +51,26 @@ config ATA_VERBOSE_ERROR ...@@ -45,9 +51,26 @@ config ATA_VERBOSE_ERROR
If unsure, say Y. If unsure, say Y.
config ATA_FORCE
bool "\"libata.force=\" kernel parameter support" if EXPERT
default y
help
This option adds support for "libata.force=" kernel parameter for
forcing configuration settings.
For further information, please read
<file:Documentation/admin-guide/kernel-parameters.txt>.
This option will enlarge the kernel by approx. 3KB. Disable it if
kernel size is more important than ability to override the default
configuration settings.
If unsure, say Y.
config ATA_ACPI config ATA_ACPI
bool "ATA ACPI Support" bool "ATA ACPI Support"
depends on ACPI depends on ACPI
select PATA_TIMINGS
default y default y
help help
This option adds support for ATA-related ACPI objects. This option adds support for ATA-related ACPI objects.
...@@ -73,6 +96,7 @@ config SATA_ZPODD ...@@ -73,6 +96,7 @@ config SATA_ZPODD
config SATA_PMP config SATA_PMP
bool "SATA Port Multiplier support" bool "SATA Port Multiplier support"
depends on SATA_HOST
default y default y
help help
This option adds support for SATA Port Multipliers This option adds support for SATA Port Multipliers
...@@ -85,6 +109,7 @@ comment "Controllers with non-SFF native interface" ...@@ -85,6 +109,7 @@ comment "Controllers with non-SFF native interface"
config SATA_AHCI config SATA_AHCI
tristate "AHCI SATA support" tristate "AHCI SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for AHCI Serial ATA. This option enables support for AHCI Serial ATA.
...@@ -111,6 +136,7 @@ config SATA_MOBILE_LPM_POLICY ...@@ -111,6 +136,7 @@ config SATA_MOBILE_LPM_POLICY
config SATA_AHCI_PLATFORM config SATA_AHCI_PLATFORM
tristate "Platform AHCI SATA support" tristate "Platform AHCI SATA support"
select SATA_HOST
help help
This option enables support for Platform AHCI Serial ATA This option enables support for Platform AHCI Serial ATA
controllers. controllers.
...@@ -121,6 +147,7 @@ config AHCI_BRCM ...@@ -121,6 +147,7 @@ config AHCI_BRCM
tristate "Broadcom AHCI SATA support" tristate "Broadcom AHCI SATA support"
depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \ depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \
ARCH_BCM_63XX ARCH_BCM_63XX
select SATA_HOST
help help
This option enables support for the AHCI SATA3 controller found on This option enables support for the AHCI SATA3 controller found on
Broadcom SoC's. Broadcom SoC's.
...@@ -130,6 +157,7 @@ config AHCI_BRCM ...@@ -130,6 +157,7 @@ config AHCI_BRCM
config AHCI_DA850 config AHCI_DA850
tristate "DaVinci DA850 AHCI SATA support" tristate "DaVinci DA850 AHCI SATA support"
depends on ARCH_DAVINCI_DA850 depends on ARCH_DAVINCI_DA850
select SATA_HOST
help help
This option enables support for the DaVinci DA850 SoC's This option enables support for the DaVinci DA850 SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -139,6 +167,7 @@ config AHCI_DA850 ...@@ -139,6 +167,7 @@ config AHCI_DA850
config AHCI_DM816 config AHCI_DM816
tristate "DaVinci DM816 AHCI SATA support" tristate "DaVinci DM816 AHCI SATA support"
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS
select SATA_HOST
help help
This option enables support for the DaVinci DM816 SoC's This option enables support for the DaVinci DM816 SoC's
onboard AHCI SATA controller. onboard AHCI SATA controller.
...@@ -148,6 +177,7 @@ config AHCI_DM816 ...@@ -148,6 +177,7 @@ config AHCI_DM816
config AHCI_ST config AHCI_ST
tristate "ST AHCI SATA support" tristate "ST AHCI SATA support"
depends on ARCH_STI depends on ARCH_STI
select SATA_HOST
help help
This option enables support for ST AHCI SATA controller. This option enables support for ST AHCI SATA controller.
...@@ -157,6 +187,7 @@ config AHCI_IMX ...@@ -157,6 +187,7 @@ config AHCI_IMX
tristate "Freescale i.MX AHCI SATA support" tristate "Freescale i.MX AHCI SATA support"
depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON
select SATA_HOST
help help
This option enables support for the Freescale i.MX SoC's This option enables support for the Freescale i.MX SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -166,6 +197,7 @@ config AHCI_IMX ...@@ -166,6 +197,7 @@ config AHCI_IMX
config AHCI_CEVA config AHCI_CEVA
tristate "CEVA AHCI SATA support" tristate "CEVA AHCI SATA support"
depends on OF depends on OF
select SATA_HOST
help help
This option enables support for the CEVA AHCI SATA. This option enables support for the CEVA AHCI SATA.
It can be found on the Xilinx Zynq UltraScale+ MPSoC. It can be found on the Xilinx Zynq UltraScale+ MPSoC.
...@@ -176,6 +208,7 @@ config AHCI_MTK ...@@ -176,6 +208,7 @@ config AHCI_MTK
tristate "MediaTek AHCI SATA support" tristate "MediaTek AHCI SATA support"
depends on ARCH_MEDIATEK depends on ARCH_MEDIATEK
select MFD_SYSCON select MFD_SYSCON
select SATA_HOST
help help
This option enables support for the MediaTek SoC's This option enables support for the MediaTek SoC's
onboard AHCI SATA controller. onboard AHCI SATA controller.
...@@ -185,6 +218,7 @@ config AHCI_MTK ...@@ -185,6 +218,7 @@ config AHCI_MTK
config AHCI_MVEBU config AHCI_MVEBU
tristate "Marvell EBU AHCI SATA support" tristate "Marvell EBU AHCI SATA support"
depends on ARCH_MVEBU depends on ARCH_MVEBU
select SATA_HOST
help help
This option enables support for the Marvebu EBU SoC's This option enables support for the Marvebu EBU SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -203,6 +237,7 @@ config AHCI_OCTEON ...@@ -203,6 +237,7 @@ config AHCI_OCTEON
config AHCI_SUNXI config AHCI_SUNXI
tristate "Allwinner sunxi AHCI SATA support" tristate "Allwinner sunxi AHCI SATA support"
depends on ARCH_SUNXI depends on ARCH_SUNXI
select SATA_HOST
help help
This option enables support for the Allwinner sunxi SoC's This option enables support for the Allwinner sunxi SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -212,6 +247,7 @@ config AHCI_SUNXI ...@@ -212,6 +247,7 @@ config AHCI_SUNXI
config AHCI_TEGRA config AHCI_TEGRA
tristate "NVIDIA Tegra AHCI SATA support" tristate "NVIDIA Tegra AHCI SATA support"
depends on ARCH_TEGRA depends on ARCH_TEGRA
select SATA_HOST
help help
This option enables support for the NVIDIA Tegra SoC's This option enables support for the NVIDIA Tegra SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -221,12 +257,14 @@ config AHCI_TEGRA ...@@ -221,12 +257,14 @@ config AHCI_TEGRA
config AHCI_XGENE config AHCI_XGENE
tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
depends on PHY_XGENE depends on PHY_XGENE
select SATA_HOST
help help
This option enables support for APM X-Gene SoC SATA host controller. This option enables support for APM X-Gene SoC SATA host controller.
config AHCI_QORIQ config AHCI_QORIQ
tristate "Freescale QorIQ AHCI SATA support" tristate "Freescale QorIQ AHCI SATA support"
depends on OF depends on OF
select SATA_HOST
help help
This option enables support for the Freescale QorIQ AHCI SoC's This option enables support for the Freescale QorIQ AHCI SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -236,6 +274,7 @@ config AHCI_QORIQ ...@@ -236,6 +274,7 @@ config AHCI_QORIQ
config SATA_FSL config SATA_FSL
tristate "Freescale 3.0Gbps SATA support" tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC depends on FSL_SOC
select SATA_HOST
help help
This option enables support for Freescale 3.0Gbps SATA controller. This option enables support for Freescale 3.0Gbps SATA controller.
It can be found on MPC837x and MPC8315. It can be found on MPC837x and MPC8315.
...@@ -245,6 +284,7 @@ config SATA_FSL ...@@ -245,6 +284,7 @@ config SATA_FSL
config SATA_GEMINI config SATA_GEMINI
tristate "Gemini SATA bridge support" tristate "Gemini SATA bridge support"
depends on ARCH_GEMINI || COMPILE_TEST depends on ARCH_GEMINI || COMPILE_TEST
select SATA_HOST
default ARCH_GEMINI default ARCH_GEMINI
help help
This enabled support for the FTIDE010 to SATA bridge This enabled support for the FTIDE010 to SATA bridge
...@@ -255,6 +295,7 @@ config SATA_GEMINI ...@@ -255,6 +295,7 @@ config SATA_GEMINI
config SATA_AHCI_SEATTLE config SATA_AHCI_SEATTLE
tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support"
depends on ARCH_SEATTLE depends on ARCH_SEATTLE
select SATA_HOST
help help
This option enables support for AMD Seattle SATA host controller. This option enables support for AMD Seattle SATA host controller.
...@@ -263,12 +304,14 @@ config SATA_AHCI_SEATTLE ...@@ -263,12 +304,14 @@ config SATA_AHCI_SEATTLE
config SATA_INIC162X config SATA_INIC162X
tristate "Initio 162x SATA support (Very Experimental)" tristate "Initio 162x SATA support (Very Experimental)"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Initio 162x Serial ATA. This option enables support for Initio 162x Serial ATA.
config SATA_ACARD_AHCI config SATA_ACARD_AHCI
tristate "ACard AHCI variant (ATP 8620)" tristate "ACard AHCI variant (ATP 8620)"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Acard. This option enables support for Acard.
...@@ -277,6 +320,7 @@ config SATA_ACARD_AHCI ...@@ -277,6 +320,7 @@ config SATA_ACARD_AHCI
config SATA_SIL24 config SATA_SIL24
tristate "Silicon Image 3124/3132 SATA support" tristate "Silicon Image 3124/3132 SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Silicon Image 3124/3132 Serial ATA. This option enables support for Silicon Image 3124/3132 Serial ATA.
...@@ -317,6 +361,7 @@ config PDC_ADMA ...@@ -317,6 +361,7 @@ config PDC_ADMA
config PATA_OCTEON_CF config PATA_OCTEON_CF
tristate "OCTEON Boot Bus Compact Flash support" tristate "OCTEON Boot Bus Compact Flash support"
depends on CAVIUM_OCTEON_SOC depends on CAVIUM_OCTEON_SOC
select PATA_TIMINGS
help help
This option enables a polled compact flash driver for use with This option enables a polled compact flash driver for use with
compact flash cards attached to the OCTEON boot bus. compact flash cards attached to the OCTEON boot bus.
...@@ -326,6 +371,7 @@ config PATA_OCTEON_CF ...@@ -326,6 +371,7 @@ config PATA_OCTEON_CF
config SATA_QSTOR config SATA_QSTOR
tristate "Pacific Digital SATA QStor support" tristate "Pacific Digital SATA QStor support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Pacific Digital Serial ATA QStor. This option enables support for Pacific Digital Serial ATA QStor.
...@@ -334,6 +380,7 @@ config SATA_QSTOR ...@@ -334,6 +380,7 @@ config SATA_QSTOR
config SATA_SX4 config SATA_SX4
tristate "Promise SATA SX4 support (Experimental)" tristate "Promise SATA SX4 support (Experimental)"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Promise Serial ATA SX4. This option enables support for Promise Serial ATA SX4.
...@@ -357,6 +404,7 @@ comment "SATA SFF controllers with BMDMA" ...@@ -357,6 +404,7 @@ comment "SATA SFF controllers with BMDMA"
config ATA_PIIX config ATA_PIIX
tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for ICH5/6/7/8 Serial ATA This option enables support for ICH5/6/7/8 Serial ATA
and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
...@@ -368,6 +416,7 @@ config SATA_DWC ...@@ -368,6 +416,7 @@ config SATA_DWC
tristate "DesignWare Cores SATA support" tristate "DesignWare Cores SATA support"
depends on DMADEVICES depends on DMADEVICES
select GENERIC_PHY select GENERIC_PHY
select SATA_HOST
help help
This option enables support for the on-chip SATA controller of the This option enables support for the on-chip SATA controller of the
AppliedMicro processor 460EX. AppliedMicro processor 460EX.
...@@ -398,6 +447,7 @@ config SATA_DWC_VDEBUG ...@@ -398,6 +447,7 @@ config SATA_DWC_VDEBUG
config SATA_HIGHBANK config SATA_HIGHBANK
tristate "Calxeda Highbank SATA support" tristate "Calxeda Highbank SATA support"
depends on ARCH_HIGHBANK || COMPILE_TEST depends on ARCH_HIGHBANK || COMPILE_TEST
select SATA_HOST
help help
This option enables support for the Calxeda Highbank SoC's This option enables support for the Calxeda Highbank SoC's
onboard SATA. onboard SATA.
...@@ -409,6 +459,7 @@ config SATA_MV ...@@ -409,6 +459,7 @@ config SATA_MV
depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \ depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \
ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST
select GENERIC_PHY select GENERIC_PHY
select SATA_HOST
help help
This option enables support for the Marvell Serial ATA family. This option enables support for the Marvell Serial ATA family.
Currently supports 88SX[56]0[48][01] PCI(-X) chips, Currently supports 88SX[56]0[48][01] PCI(-X) chips,
...@@ -419,6 +470,7 @@ config SATA_MV ...@@ -419,6 +470,7 @@ config SATA_MV
config SATA_NV config SATA_NV
tristate "NVIDIA SATA support" tristate "NVIDIA SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for NVIDIA Serial ATA. This option enables support for NVIDIA Serial ATA.
...@@ -427,6 +479,7 @@ config SATA_NV ...@@ -427,6 +479,7 @@ config SATA_NV
config SATA_PROMISE config SATA_PROMISE
tristate "Promise SATA TX2/TX4 support" tristate "Promise SATA TX2/TX4 support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Promise Serial ATA TX2/TX4. This option enables support for Promise Serial ATA TX2/TX4.
...@@ -435,6 +488,7 @@ config SATA_PROMISE ...@@ -435,6 +488,7 @@ config SATA_PROMISE
config SATA_RCAR config SATA_RCAR
tristate "Renesas R-Car SATA support" tristate "Renesas R-Car SATA support"
depends on ARCH_RENESAS || COMPILE_TEST depends on ARCH_RENESAS || COMPILE_TEST
select SATA_HOST
help help
This option enables support for Renesas R-Car Serial ATA. This option enables support for Renesas R-Car Serial ATA.
...@@ -443,6 +497,7 @@ config SATA_RCAR ...@@ -443,6 +497,7 @@ config SATA_RCAR
config SATA_SIL config SATA_SIL
tristate "Silicon Image SATA support" tristate "Silicon Image SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Silicon Image Serial ATA. This option enables support for Silicon Image Serial ATA.
...@@ -452,6 +507,7 @@ config SATA_SIS ...@@ -452,6 +507,7 @@ config SATA_SIS
tristate "SiS 964/965/966/180 SATA support" tristate "SiS 964/965/966/180 SATA support"
depends on PCI depends on PCI
select PATA_SIS select PATA_SIS
select SATA_HOST
help help
This option enables support for SiS Serial ATA on This option enables support for SiS Serial ATA on
SiS 964/965/966/180 and Parallel ATA on SiS 180. SiS 964/965/966/180 and Parallel ATA on SiS 180.
...@@ -462,6 +518,7 @@ config SATA_SIS ...@@ -462,6 +518,7 @@ config SATA_SIS
config SATA_SVW config SATA_SVW
tristate "ServerWorks Frodo / Apple K2 SATA support" tristate "ServerWorks Frodo / Apple K2 SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Broadcom/Serverworks/Apple K2 This option enables support for Broadcom/Serverworks/Apple K2
SATA support. SATA support.
...@@ -471,6 +528,7 @@ config SATA_SVW ...@@ -471,6 +528,7 @@ config SATA_SVW
config SATA_ULI config SATA_ULI
tristate "ULi Electronics SATA support" tristate "ULi Electronics SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for ULi Electronics SATA. This option enables support for ULi Electronics SATA.
...@@ -479,6 +537,7 @@ config SATA_ULI ...@@ -479,6 +537,7 @@ config SATA_ULI
config SATA_VIA config SATA_VIA
tristate "VIA SATA support" tristate "VIA SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for VIA Serial ATA. This option enables support for VIA Serial ATA.
...@@ -487,6 +546,7 @@ config SATA_VIA ...@@ -487,6 +546,7 @@ config SATA_VIA
config SATA_VITESSE config SATA_VITESSE
tristate "VITESSE VSC-7174 / INTEL 31244 SATA support" tristate "VITESSE VSC-7174 / INTEL 31244 SATA support"
depends on PCI depends on PCI
select SATA_HOST
help help
This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA. This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA.
...@@ -497,6 +557,7 @@ comment "PATA SFF controllers with BMDMA" ...@@ -497,6 +557,7 @@ comment "PATA SFF controllers with BMDMA"
config PATA_ALI config PATA_ALI
tristate "ALi PATA support" tristate "ALi PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the ALi ATA interfaces This option enables support for the ALi ATA interfaces
found on the many ALi chipsets. found on the many ALi chipsets.
...@@ -506,6 +567,7 @@ config PATA_ALI ...@@ -506,6 +567,7 @@ config PATA_ALI
config PATA_AMD config PATA_AMD
tristate "AMD/NVidia PATA support" tristate "AMD/NVidia PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the AMD and NVidia PATA This option enables support for the AMD and NVidia PATA
interfaces found on the chipsets for Athlon/Athlon64. interfaces found on the chipsets for Athlon/Athlon64.
...@@ -540,6 +602,7 @@ config PATA_ATIIXP ...@@ -540,6 +602,7 @@ config PATA_ATIIXP
config PATA_ATP867X config PATA_ATP867X
tristate "ARTOP/Acard ATP867X PATA support" tristate "ARTOP/Acard ATP867X PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for ARTOP/Acard ATP867X PATA This option enables support for ARTOP/Acard ATP867X PATA
controllers. controllers.
...@@ -549,6 +612,7 @@ config PATA_ATP867X ...@@ -549,6 +612,7 @@ config PATA_ATP867X
config PATA_BK3710 config PATA_BK3710
tristate "Palmchip BK3710 PATA support" tristate "Palmchip BK3710 PATA support"
depends on ARCH_DAVINCI depends on ARCH_DAVINCI
select PATA_TIMINGS
help help
This option enables support for the integrated IDE controller on This option enables support for the integrated IDE controller on
the TI DaVinci SoC. the TI DaVinci SoC.
...@@ -558,6 +622,7 @@ config PATA_BK3710 ...@@ -558,6 +622,7 @@ config PATA_BK3710
config PATA_CMD64X config PATA_CMD64X
tristate "CMD64x PATA support" tristate "CMD64x PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the CMD64x series chips This option enables support for the CMD64x series chips
except for the CMD640. except for the CMD640.
...@@ -603,6 +668,7 @@ config PATA_CS5536 ...@@ -603,6 +668,7 @@ config PATA_CS5536
config PATA_CYPRESS config PATA_CYPRESS
tristate "Cypress CY82C693 PATA support (Very Experimental)" tristate "Cypress CY82C693 PATA support (Very Experimental)"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the Cypress/Contaq CY82C693 This option enables support for the Cypress/Contaq CY82C693
chipset found in some Alpha systems chipset found in some Alpha systems
...@@ -621,6 +687,7 @@ config PATA_EFAR ...@@ -621,6 +687,7 @@ config PATA_EFAR
config PATA_EP93XX config PATA_EP93XX
tristate "Cirrus Logic EP93xx PATA support" tristate "Cirrus Logic EP93xx PATA support"
depends on ARCH_EP93XX depends on ARCH_EP93XX
select PATA_TIMINGS
help help
This option enables support for the PATA controller in This option enables support for the PATA controller in
the Cirrus Logic EP9312 and EP9315 ARM CPU. the Cirrus Logic EP9312 and EP9315 ARM CPU.
...@@ -685,6 +752,7 @@ config PATA_HPT3X3_DMA ...@@ -685,6 +752,7 @@ config PATA_HPT3X3_DMA
config PATA_ICSIDE config PATA_ICSIDE
tristate "Acorn ICS PATA support" tristate "Acorn ICS PATA support"
depends on ARM && ARCH_ACORN depends on ARM && ARCH_ACORN
select PATA_TIMINGS
help help
On Acorn systems, say Y here if you wish to use the ICS PATA On Acorn systems, say Y here if you wish to use the ICS PATA
interface card. This is not required for ICS partition support. interface card. This is not required for ICS partition support.
...@@ -693,6 +761,7 @@ config PATA_ICSIDE ...@@ -693,6 +761,7 @@ config PATA_ICSIDE
config PATA_IMX config PATA_IMX
tristate "PATA support for Freescale iMX" tristate "PATA support for Freescale iMX"
depends on ARCH_MXC depends on ARCH_MXC
select PATA_TIMINGS
help help
This option enables support for the PATA host available on Freescale This option enables support for the PATA host available on Freescale
iMX SoCs. iMX SoCs.
...@@ -778,6 +847,7 @@ config PATA_NINJA32 ...@@ -778,6 +847,7 @@ config PATA_NINJA32
config PATA_NS87415 config PATA_NS87415
tristate "Nat Semi NS87415 PATA support" tristate "Nat Semi NS87415 PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the National Semiconductor This option enables support for the National Semiconductor
NS87415 PCI-IDE controller. NS87415 PCI-IDE controller.
...@@ -902,6 +972,7 @@ config PATA_TRIFLEX ...@@ -902,6 +972,7 @@ config PATA_TRIFLEX
config PATA_VIA config PATA_VIA
tristate "VIA PATA support" tristate "VIA PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the VIA PATA interfaces This option enables support for the VIA PATA interfaces
found on the many VIA chipsets. found on the many VIA chipsets.
...@@ -935,6 +1006,7 @@ comment "PIO-only SFF controllers" ...@@ -935,6 +1006,7 @@ comment "PIO-only SFF controllers"
config PATA_CMD640_PCI config PATA_CMD640_PCI
tristate "CMD640 PCI PATA support (Experimental)" tristate "CMD640 PCI PATA support (Experimental)"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the CMD640 PCI IDE This option enables support for the CMD640 PCI IDE
interface chip. Only the primary channel is currently interface chip. Only the primary channel is currently
...@@ -1005,6 +1077,7 @@ config PATA_MPIIX ...@@ -1005,6 +1077,7 @@ config PATA_MPIIX
config PATA_NS87410 config PATA_NS87410
tristate "Nat Semi NS87410 PATA support" tristate "Nat Semi NS87410 PATA support"
depends on PCI depends on PCI
select PATA_TIMINGS
help help
This option enables support for the National Semiconductor This option enables support for the National Semiconductor
NS87410 PCI-IDE controller. NS87410 PCI-IDE controller.
...@@ -1085,6 +1158,7 @@ config PATA_RZ1000 ...@@ -1085,6 +1158,7 @@ config PATA_RZ1000
config PATA_SAMSUNG_CF config PATA_SAMSUNG_CF
tristate "Samsung SoC PATA support" tristate "Samsung SoC PATA support"
depends on SAMSUNG_DEV_IDE depends on SAMSUNG_DEV_IDE
select PATA_TIMINGS
help help
This option enables basic support for Samsung's S3C/S5P board This option enables basic support for Samsung's S3C/S5P board
PATA controllers via the new ATA layer PATA controllers via the new ATA layer
...@@ -1104,6 +1178,7 @@ comment "Generic fallback / legacy drivers" ...@@ -1104,6 +1178,7 @@ comment "Generic fallback / legacy drivers"
config PATA_ACPI config PATA_ACPI
tristate "ACPI firmware driver for PATA" tristate "ACPI firmware driver for PATA"
depends on ATA_ACPI && ATA_BMDMA && PCI depends on ATA_ACPI && ATA_BMDMA && PCI
select PATA_TIMINGS
help help
This option enables an ACPI method driver which drives This option enables an ACPI method driver which drives
motherboard PATA controller interfaces through the ACPI motherboard PATA controller interfaces through the ACPI
...@@ -1113,6 +1188,7 @@ config PATA_ACPI ...@@ -1113,6 +1188,7 @@ config PATA_ACPI
config ATA_GENERIC config ATA_GENERIC
tristate "Generic ATA support" tristate "Generic ATA support"
depends on PCI && ATA_BMDMA depends on PCI && ATA_BMDMA
select SATA_HOST
help help
This option enables support for generic BIOS configured This option enables support for generic BIOS configured
ATA controllers via the new ATA layer ATA controllers via the new ATA layer
...@@ -1122,6 +1198,7 @@ config ATA_GENERIC ...@@ -1122,6 +1198,7 @@ config ATA_GENERIC
config PATA_LEGACY config PATA_LEGACY
tristate "Legacy ISA PATA support (Experimental)" tristate "Legacy ISA PATA support (Experimental)"
depends on (ISA || PCI) depends on (ISA || PCI)
select PATA_TIMINGS
help help
This option enables support for ISA/VLB/PCI bus legacy PATA This option enables support for ISA/VLB/PCI bus legacy PATA
ports and allows them to be accessed via the new ATA layer. ports and allows them to be accessed via the new ATA layer.
......
...@@ -123,7 +123,9 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o ...@@ -123,7 +123,9 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-y := libata-core.o libata-scsi.o libata-eh.o \ libata-y := libata-core.o libata-scsi.o libata-eh.o \
libata-transport.o libata-trace.o libata-transport.o libata-trace.o
libata-$(CONFIG_SATA_HOST) += libata-sata.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o
libata-$(CONFIG_PATA_TIMINGS) += libata-pata-timings.o
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
enum { enum {
AHCI_PCI_BAR_STA2X11 = 0, AHCI_PCI_BAR_STA2X11 = 0,
AHCI_PCI_BAR_CAVIUM = 0, AHCI_PCI_BAR_CAVIUM = 0,
AHCI_PCI_BAR_LOONGSON = 0,
AHCI_PCI_BAR_ENMOTUS = 2, AHCI_PCI_BAR_ENMOTUS = 2,
AHCI_PCI_BAR_CAVIUM_GEN5 = 4, AHCI_PCI_BAR_CAVIUM_GEN5 = 4,
AHCI_PCI_BAR_STANDARD = 5, AHCI_PCI_BAR_STANDARD = 5,
...@@ -245,6 +246,7 @@ static const struct ata_port_info ahci_port_info[] = { ...@@ -245,6 +246,7 @@ static const struct ata_port_info ahci_port_info[] = {
static const struct pci_device_id ahci_pci_tbl[] = { static const struct pci_device_id ahci_pci_tbl[] = {
/* Intel */ /* Intel */
{ PCI_VDEVICE(INTEL, 0x06d6), board_ahci }, /* Comet Lake PCH-H RAID */
{ PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */ { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
{ PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */ { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
...@@ -401,6 +403,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -401,6 +403,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
{ PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */
{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
...@@ -589,6 +593,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -589,6 +593,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Enmotus */ /* Enmotus */
{ PCI_DEVICE(0x1c44, 0x8000), board_ahci }, { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
/* Loongson */
{ PCI_VDEVICE(LOONGSON, 0x7a08), board_ahci },
/* Generic, PCI class code for AHCI */ /* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
...@@ -1680,6 +1687,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1680,6 +1687,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM; ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
if (pdev->device == 0xa084) if (pdev->device == 0xa084)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5; ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5;
} else if (pdev->vendor == PCI_VENDOR_ID_LOONGSON) {
if (pdev->device == 0x7a08)
ahci_pci_bar = AHCI_PCI_BAR_LOONGSON;
} }
/* acquire resources */ /* acquire resources */
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-core.c - helper library for ATA * 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 Red Hat, Inc. All rights reserved.
* Copyright 2003-2004 Jeff Garzik * Copyright 2003-2004 Jeff Garzik
* *
...@@ -22,6 +18,11 @@ ...@@ -22,6 +18,11 @@
* http://www.compactflash.org (CF) * http://www.compactflash.org (CF)
* http://www.qic.org (QIC157 - Tape and DSC) * http://www.qic.org (QIC157 - Tape and DSC)
* http://www.ce-ata.org (CE-ATA: not supported) * 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> #include <linux/kernel.h>
...@@ -56,6 +57,7 @@ ...@@ -56,6 +57,7 @@
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/setup.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/libata.h> #include <trace/events/libata.h>
...@@ -63,11 +65,6 @@ ...@@ -63,11 +65,6 @@
#include "libata.h" #include "libata.h"
#include "libata-transport.h" #include "libata-transport.h"
/* debounce timing parameters in msecs { interval, duration, timeout } */
const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
const struct ata_port_operations ata_base_port_ops = { const struct ata_port_operations ata_base_port_ops = {
.prereset = ata_std_prereset, .prereset = ata_std_prereset,
.postreset = ata_std_postreset, .postreset = ata_std_postreset,
...@@ -82,6 +79,7 @@ const struct ata_port_operations sata_port_ops = { ...@@ -82,6 +79,7 @@ const struct ata_port_operations sata_port_ops = {
.qc_defer = ata_std_qc_defer, .qc_defer = ata_std_qc_defer,
.hardreset = sata_std_hardreset, .hardreset = sata_std_hardreset,
}; };
EXPORT_SYMBOL_GPL(sata_port_ops);
static unsigned int ata_dev_init_params(struct ata_device *dev, static unsigned int ata_dev_init_params(struct ata_device *dev,
u16 heads, u16 sectors); u16 heads, u16 sectors);
...@@ -91,14 +89,15 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev); ...@@ -91,14 +89,15 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
atomic_t ata_print_id = ATOMIC_INIT(0); atomic_t ata_print_id = ATOMIC_INIT(0);
#ifdef CONFIG_ATA_FORCE
struct ata_force_param { struct ata_force_param {
const char *name; const char *name;
unsigned int cbl; u8 cbl;
int spd_limit; u8 spd_limit;
unsigned long xfer_mask; unsigned long xfer_mask;
unsigned int horkage_on; unsigned int horkage_on;
unsigned int horkage_off; unsigned int horkage_off;
unsigned int lflags; u16 lflags;
}; };
struct ata_force_ent { struct ata_force_ent {
...@@ -110,10 +109,11 @@ struct ata_force_ent { ...@@ -110,10 +109,11 @@ struct ata_force_ent {
static struct ata_force_ent *ata_force_tbl; static struct ata_force_ent *ata_force_tbl;
static int ata_force_tbl_size; 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 */ /* param_buf is thrown away after initialization, disallow read */
module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); 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)"); MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/admin-guide/kernel-parameters.rst for details)");
#endif
static int atapi_enabled = 1; static int atapi_enabled = 1;
module_param(atapi_enabled, int, 0444); module_param(atapi_enabled, int, 0444);
...@@ -224,6 +224,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap, ...@@ -224,6 +224,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap,
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(ata_link_next);
/** /**
* ata_dev_next - device iteration helper * ata_dev_next - device iteration helper
...@@ -277,6 +278,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link, ...@@ -277,6 +278,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link,
goto next; goto next;
return dev; return dev;
} }
EXPORT_SYMBOL_GPL(ata_dev_next);
/** /**
* ata_dev_phys_link - find physical link for a device * ata_dev_phys_link - find physical link for a device
...@@ -303,6 +305,7 @@ struct ata_link *ata_dev_phys_link(struct ata_device *dev) ...@@ -303,6 +305,7 @@ struct ata_link *ata_dev_phys_link(struct ata_device *dev)
return ap->slave_link; return ap->slave_link;
} }
#ifdef CONFIG_ATA_FORCE
/** /**
* ata_force_cbl - force cable type according to libata.force * ata_force_cbl - force cable type according to libata.force
* @ap: ATA port of interest * @ap: ATA port of interest
...@@ -483,6 +486,11 @@ static void ata_force_horkage(struct ata_device *dev) ...@@ -483,6 +486,11 @@ static void ata_force_horkage(struct ata_device *dev)
fe->param.name); fe->param.name);
} }
} }
#else
static inline void ata_force_link_limits(struct ata_link *link) { }
static inline void ata_force_xfermask(struct ata_device *dev) { }
static inline void ata_force_horkage(struct ata_device *dev) { }
#endif
/** /**
* atapi_cmd_type - Determine ATAPI command type from SCSI opcode * atapi_cmd_type - Determine ATAPI command type from SCSI opcode
...@@ -521,79 +529,7 @@ int atapi_cmd_type(u8 opcode) ...@@ -521,79 +529,7 @@ int atapi_cmd_type(u8 opcode)
return ATAPI_MISC; return ATAPI_MISC;
} }
} }
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;
}
/**
* 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];
}
static const u8 ata_rw_cmds[] = { static const u8 ata_rw_cmds[] = {
/* pio multi */ /* pio multi */
...@@ -868,6 +804,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask, ...@@ -868,6 +804,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask,
((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); ((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 * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks
...@@ -923,6 +860,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask) ...@@ -923,6 +860,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask)
return ent->base + highbit - ent->shift; return ent->base + highbit - ent->shift;
return 0xff; return 0xff;
} }
EXPORT_SYMBOL_GPL(ata_xfer_mask2mode);
/** /**
* ata_xfer_mode2mask - Find matching xfer_mask for XFER_* * ata_xfer_mode2mask - Find matching xfer_mask for XFER_*
...@@ -946,6 +884,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode) ...@@ -946,6 +884,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode)
& ~((1 << ent->shift) - 1); & ~((1 << ent->shift) - 1);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
/** /**
* ata_xfer_mode2shift - Find matching xfer_shift for XFER_* * ata_xfer_mode2shift - Find matching xfer_shift for XFER_*
...@@ -968,6 +907,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode) ...@@ -968,6 +907,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode)
return ent->shift; return ent->shift;
return -1; return -1;
} }
EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
/** /**
* ata_mode_string - convert xfer_mask to string * ata_mode_string - convert xfer_mask to string
...@@ -1014,6 +954,7 @@ const char *ata_mode_string(unsigned long xfer_mask) ...@@ -1014,6 +954,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
return xfer_mode_str[highbit]; return xfer_mode_str[highbit];
return "<n/a>"; return "<n/a>";
} }
EXPORT_SYMBOL_GPL(ata_mode_string);
const char *sata_spd_string(unsigned int spd) const char *sata_spd_string(unsigned int spd)
{ {
...@@ -1094,6 +1035,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) ...@@ -1094,6 +1035,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
DPRINTK("unknown device\n"); DPRINTK("unknown device\n");
return ATA_DEV_UNKNOWN; return ATA_DEV_UNKNOWN;
} }
EXPORT_SYMBOL_GPL(ata_dev_classify);
/** /**
* ata_id_string - Convert IDENTIFY DEVICE page into string * ata_id_string - Convert IDENTIFY DEVICE page into string
...@@ -1130,6 +1072,7 @@ void ata_id_string(const u16 *id, unsigned char *s, ...@@ -1130,6 +1072,7 @@ void ata_id_string(const u16 *id, unsigned char *s,
len -= 2; len -= 2;
} }
} }
EXPORT_SYMBOL_GPL(ata_id_string);
/** /**
* ata_id_c_string - Convert IDENTIFY DEVICE page into C string * ata_id_c_string - Convert IDENTIFY DEVICE page into C string
...@@ -1157,6 +1100,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s, ...@@ -1157,6 +1100,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
p--; p--;
*p = '\0'; *p = '\0';
} }
EXPORT_SYMBOL_GPL(ata_id_c_string);
static u64 ata_id_n_sectors(const u16 *id) static u64 ata_id_n_sectors(const u16 *id)
{ {
...@@ -1514,6 +1458,7 @@ unsigned long ata_id_xfermask(const u16 *id) ...@@ -1514,6 +1458,7 @@ unsigned long ata_id_xfermask(const u16 *id)
return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); 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) static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
{ {
...@@ -1771,6 +1716,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) ...@@ -1771,6 +1716,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
return 1; return 1;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
/** /**
* ata_pio_mask_no_iordy - Return the non IORDY mask * ata_pio_mask_no_iordy - Return the non IORDY mask
...@@ -1811,6 +1757,7 @@ unsigned int ata_do_dev_read_id(struct ata_device *dev, ...@@ -1811,6 +1757,7 @@ unsigned int ata_do_dev_read_id(struct ata_device *dev,
return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS, 0); 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 * ata_dev_read_id - Read ID data from the specified device
...@@ -2265,6 +2212,8 @@ static int ata_dev_config_ncq(struct ata_device *dev, ...@@ -2265,6 +2212,8 @@ static int ata_dev_config_ncq(struct ata_device *dev,
desc[0] = '\0'; desc[0] = '\0';
return 0; return 0;
} }
if (!IS_ENABLED(CONFIG_SATA_HOST))
return 0;
if (dev->horkage & ATA_HORKAGE_NONCQ) { if (dev->horkage & ATA_HORKAGE_NONCQ) {
snprintf(desc, desc_sz, "NCQ (not used)"); snprintf(desc, desc_sz, "NCQ (not used)");
return 0; return 0;
...@@ -2783,6 +2732,7 @@ int ata_cable_40wire(struct ata_port *ap) ...@@ -2783,6 +2732,7 @@ int ata_cable_40wire(struct ata_port *ap)
{ {
return ATA_CBL_PATA40; return ATA_CBL_PATA40;
} }
EXPORT_SYMBOL_GPL(ata_cable_40wire);
/** /**
* ata_cable_80wire - return 80 wire cable type * ata_cable_80wire - return 80 wire cable type
...@@ -2796,6 +2746,7 @@ int ata_cable_80wire(struct ata_port *ap) ...@@ -2796,6 +2746,7 @@ int ata_cable_80wire(struct ata_port *ap)
{ {
return ATA_CBL_PATA80; return ATA_CBL_PATA80;
} }
EXPORT_SYMBOL_GPL(ata_cable_80wire);
/** /**
* ata_cable_unknown - return unknown PATA cable. * ata_cable_unknown - return unknown PATA cable.
...@@ -2808,6 +2759,7 @@ int ata_cable_unknown(struct ata_port *ap) ...@@ -2808,6 +2759,7 @@ int ata_cable_unknown(struct ata_port *ap)
{ {
return ATA_CBL_PATA_UNK; return ATA_CBL_PATA_UNK;
} }
EXPORT_SYMBOL_GPL(ata_cable_unknown);
/** /**
* ata_cable_ignore - return ignored PATA cable. * ata_cable_ignore - return ignored PATA cable.
...@@ -2820,6 +2772,7 @@ int ata_cable_ignore(struct ata_port *ap) ...@@ -2820,6 +2772,7 @@ int ata_cable_ignore(struct ata_port *ap)
{ {
return ATA_CBL_PATA_IGN; return ATA_CBL_PATA_IGN;
} }
EXPORT_SYMBOL_GPL(ata_cable_ignore);
/** /**
* ata_cable_sata - return SATA cable type * ata_cable_sata - return SATA cable type
...@@ -2832,6 +2785,7 @@ int ata_cable_sata(struct ata_port *ap) ...@@ -2832,6 +2785,7 @@ int ata_cable_sata(struct ata_port *ap)
{ {
return ATA_CBL_SATA; return ATA_CBL_SATA;
} }
EXPORT_SYMBOL_GPL(ata_cable_sata);
/** /**
* ata_bus_probe - Reset and probe ATA bus * ata_bus_probe - Reset and probe ATA bus
...@@ -3014,6 +2968,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) ...@@ -3014,6 +2968,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
return NULL; return NULL;
return pair; return pair;
} }
EXPORT_SYMBOL_GPL(ata_dev_pair);
/** /**
* sata_down_spd_limit - adjust SATA spd limit downward * sata_down_spd_limit - adjust SATA spd limit downward
...@@ -3095,252 +3050,7 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) ...@@ -3095,252 +3050,7 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
return 0; return 0;
} }
static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) #ifdef CONFIG_ATA_ACPI
{
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;
}
/*
* 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);
}
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;
}
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;
}
/** /**
* ata_timing_cycle2mode - find xfer mode for the specified cycle duration * ata_timing_cycle2mode - find xfer mode for the specified cycle duration
* @xfer_shift: ATA_SHIFT_* value for transfer type to examine. * @xfer_shift: ATA_SHIFT_* value for transfer type to examine.
...@@ -3391,6 +3101,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) ...@@ -3391,6 +3101,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle)
return last_mode; return last_mode;
} }
#endif
/** /**
* ata_down_xfermask_limit - adjust dev xfer masks downward * ata_down_xfermask_limit - adjust dev xfer masks downward
...@@ -3662,6 +3373,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) ...@@ -3662,6 +3373,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
*r_failed_dev = dev; *r_failed_dev = dev;
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_do_set_mode);
/** /**
* ata_wait_ready - wait for link to become ready * ata_wait_ready - wait for link to become ready
...@@ -3771,417 +3483,98 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, ...@@ -3771,417 +3483,98 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
return ata_wait_ready(link, deadline, check_ready); return ata_wait_ready(link, deadline, check_ready);
} }
EXPORT_SYMBOL_GPL(ata_wait_after_reset);
/** /**
* sata_link_debounce - debounce SATA phy status * ata_std_prereset - prepare for reset
* @link: ATA link to debounce SATA phy status for * @link: ATA link to be reset
* @params: timing parameters { interval, duration, timeout } in msec
* @deadline: deadline jiffies for the operation * @deadline: deadline jiffies for the operation
* *
* Make sure SStatus of @link reaches stable state, determined by * @link is about to be reset. Initialize it. Failure from
* holding the same value where DET is not 1 for @duration polled * prereset makes libata abort whole reset sequence and give up
* every @interval, before @timeout. Timeout constraints the * that port, so prereset should be best-effort. It does its
* beginning of the stable state. Because DET gets stuck at 1 on * best to prepare for reset sequence but if things go wrong, it
* some controllers after hot unplugging, this functions waits * should just whine, not fail.
* 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: * LOCKING:
* Kernel thread context (may sleep) * Kernel thread context (may sleep)
* *
* RETURNS: * RETURNS:
* 0 on success, -errno on failure. * 0 on success, -errno otherwise.
*/ */
int sata_link_debounce(struct ata_link *link, const unsigned long *params, int ata_std_prereset(struct ata_link *link, unsigned long deadline)
unsigned long deadline)
{ {
unsigned long interval = params[0]; struct ata_port *ap = link->ap;
unsigned long duration = params[1]; struct ata_eh_context *ehc = &link->eh_context;
unsigned long last_jiffies, t; const unsigned long *timing = sata_ehc_deb_timing(ehc);
u32 last, cur;
int rc; int rc;
t = ata_deadline(jiffies, params[2]); /* if we're about to do hardreset, nothing more to do */
if (time_before(t, deadline)) if (ehc->i.action & ATA_EH_HARDRESET)
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; return 0;
continue;
/* if SATA, resume link */
if (ap->flags & ATA_FLAG_SATA) {
rc = sata_link_resume(link, timing, deadline);
/* whine about phy resume failure but proceed */
if (rc && rc != -EOPNOTSUPP)
ata_link_warn(link,
"failed to resume link for reset (errno=%d)\n",
rc);
} }
/* unstable, start over */ /* no point in trying softreset on offline link */
last = cur; if (ata_phys_link_offline(link))
last_jiffies = jiffies; ehc->i.action &= ~ATA_EH_SOFTRESET;
/* Check deadline. If debouncing failed, return return 0;
* -EPIPE to tell upper layer to lower link speed.
*/
if (time_after(jiffies, deadline))
return -EPIPE;
}
} }
EXPORT_SYMBOL_GPL(ata_std_prereset);
/** /**
* sata_link_resume - resume SATA link * sata_std_hardreset - COMRESET w/o waiting or classification
* @link: ATA link to resume SATA * @link: link to reset
* @params: timing parameters { interval, duration, timeout } in msec * @class: resulting class of attached device
* @deadline: deadline jiffies for the operation * @deadline: deadline jiffies for the operation
* *
* Resume SATA phy @link and debounce it. * Standard SATA COMRESET w/o waiting or classification.
* *
* LOCKING: * LOCKING:
* Kernel thread context (may sleep) * Kernel thread context (may sleep)
* *
* RETURNS: * RETURNS:
* 0 on success, -errno on failure. * 0 if link offline, -EAGAIN if link online, -errno on errors.
*/ */
int sata_link_resume(struct ata_link *link, const unsigned long *params, int sata_std_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline) unsigned long deadline)
{ {
int tries = ATA_LINK_RESUME_TRIES; const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
u32 scontrol, serror; bool online;
int rc; int rc;
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) /* do hardreset */
return rc; rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
return online ? -EAGAIN : 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_std_hardreset);
/** /**
* sata_link_scr_lpm - manipulate SControl IPM and SPM fields * ata_std_postreset - standard postreset callback
* @link: ATA link to manipulate SControl for * @link: the target ata_link
* @policy: LPM policy to configure * @classes: classes of attached devices
* @spm_wakeup: initiate LPM transition to active state
* *
* Manipulate the IPM field of the SControl register of @link * This function is invoked after a successful reset. Note that
* according to @policy. If @policy is ATA_LPM_MAX_POWER and * the device might have been reset more than once using
* @spm_wakeup is %true, the SPM field is manipulated to wake up * different reset methods before postreset is invoked.
* the link. This function also clears PHYRDY_CHG before
* returning.
* *
* LOCKING: * LOCKING:
* EH context. * Kernel thread context (may sleep)
*
* RETURNS:
* 0 on success, -errno otherwise.
*/ */
int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, void ata_std_postreset(struct ata_link *link, unsigned int *classes)
bool spm_wakeup)
{ {
struct ata_eh_context *ehc = &link->eh_context; u32 serror;
bool woken_up = false;
u32 scontrol;
int rc;
rc = sata_scr_read(link, SCR_CONTROL, &scontrol); DPRINTK("ENTER\n");
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);
}
/**
* ata_std_prereset - prepare for reset
* @link: ATA link to be reset
* @deadline: deadline jiffies for the operation
*
* @link is about to be reset. Initialize it. Failure from
* prereset makes libata abort whole reset sequence and give up
* that port, so prereset should be best-effort. It does its
* best to prepare for reset sequence but if things go wrong, it
* should just whine, not fail.
*
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
* 0 on success, -errno otherwise.
*/
int ata_std_prereset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context;
const unsigned long *timing = sata_ehc_deb_timing(ehc);
int rc;
/* if we're about to do hardreset, nothing more to do */
if (ehc->i.action & ATA_EH_HARDRESET)
return 0;
/* if SATA, resume link */
if (ap->flags & ATA_FLAG_SATA) {
rc = sata_link_resume(link, timing, deadline);
/* whine about phy resume failure but proceed */
if (rc && rc != -EOPNOTSUPP)
ata_link_warn(link,
"failed to resume link for reset (errno=%d)\n",
rc);
}
/* no point in trying softreset on offline link */
if (ata_phys_link_offline(link))
ehc->i.action &= ~ATA_EH_SOFTRESET;
return 0;
}
/**
* 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;
}
/**
* sata_std_hardreset - COMRESET w/o waiting or classification
* @link: link to reset
* @class: resulting class of attached device
* @deadline: deadline jiffies for the operation
*
* Standard SATA COMRESET w/o waiting or classification.
*
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
* 0 if link offline, -EAGAIN if link online, -errno on errors.
*/
int sata_std_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
bool online;
int rc;
/* do hardreset */
rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
return online ? -EAGAIN : rc;
}
/**
* ata_std_postreset - standard postreset callback
* @link: the target ata_link
* @classes: classes of attached devices
*
* This function is invoked after a successful reset. Note that
* the device might have been reset more than once using
* different reset methods before postreset is invoked.
*
* LOCKING:
* Kernel thread context (may sleep)
*/
void ata_std_postreset(struct ata_link *link, unsigned int *classes)
{
u32 serror;
DPRINTK("ENTER\n");
/* reset complete, clear SError */ /* reset complete, clear SError */
if (!sata_scr_read(link, SCR_ERROR, &serror)) if (!sata_scr_read(link, SCR_ERROR, &serror))
...@@ -4192,6 +3585,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) ...@@ -4192,6 +3585,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
EXPORT_SYMBOL_GPL(ata_std_postreset);
/** /**
* ata_dev_same_device - Determine whether new ID matches configured device * ata_dev_same_device - Determine whether new ID matches configured device
...@@ -4979,11 +4373,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) ...@@ -4979,11 +4373,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc)
return ATA_DEFER_LINK; return ATA_DEFER_LINK;
} }
EXPORT_SYMBOL_GPL(ata_std_qc_defer);
enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc) enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc)
{ {
return AC_ERR_OK; return AC_ERR_OK;
} }
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
/** /**
* ata_sg_init - Associate command with scatter-gather table. * ata_sg_init - Associate command with scatter-gather table.
...@@ -5327,6 +4723,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) ...@@ -5327,6 +4723,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
__ata_qc_complete(qc); __ata_qc_complete(qc);
} }
} }
EXPORT_SYMBOL_GPL(ata_qc_complete);
/** /**
* ata_qc_get_active - get bitmask of active qcs * ata_qc_get_active - get bitmask of active qcs
...@@ -5352,64 +4749,6 @@ u64 ata_qc_get_active(struct ata_port *ap) ...@@ -5352,64 +4749,6 @@ u64 ata_qc_get_active(struct ata_port *ap)
} }
EXPORT_SYMBOL_GPL(ata_qc_get_active); 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;
}
/** /**
* ata_qc_issue - issue taskfile to device * ata_qc_issue - issue taskfile to device
* @qc: command to issue to device * @qc: command to issue to device
...@@ -5485,111 +4824,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) ...@@ -5485,111 +4824,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
ata_qc_complete(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;
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/** /**
* ata_phys_link_online - test whether the given link is online * ata_phys_link_online - test whether the given link is online
* @link: ATA link to test * @link: ATA link to test
...@@ -5663,6 +4897,7 @@ bool ata_link_online(struct ata_link *link) ...@@ -5663,6 +4897,7 @@ bool ata_link_online(struct ata_link *link)
return ata_phys_link_online(link) || return ata_phys_link_online(link) ||
(slave && ata_phys_link_online(slave)); (slave && ata_phys_link_online(slave));
} }
EXPORT_SYMBOL_GPL(ata_link_online);
/** /**
* ata_link_offline - test whether the given link is offline * ata_link_offline - test whether the given link is offline
...@@ -5689,6 +4924,7 @@ bool ata_link_offline(struct ata_link *link) ...@@ -5689,6 +4924,7 @@ bool ata_link_offline(struct ata_link *link)
return ata_phys_link_offline(link) && return ata_phys_link_offline(link) &&
(!slave || ata_phys_link_offline(slave)); (!slave || ata_phys_link_offline(slave));
} }
EXPORT_SYMBOL_GPL(ata_link_offline);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
...@@ -5875,6 +5111,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) ...@@ -5875,6 +5111,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
host->dev->power.power_state = mesg; host->dev->power.power_state = mesg;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_host_suspend);
/** /**
* ata_host_resume - resume host * ata_host_resume - resume host
...@@ -5886,6 +5123,7 @@ void ata_host_resume(struct ata_host *host) ...@@ -5886,6 +5123,7 @@ void ata_host_resume(struct ata_host *host)
{ {
host->dev->power.power_state = PMSG_ON; host->dev->power.power_state = PMSG_ON;
} }
EXPORT_SYMBOL_GPL(ata_host_resume);
#endif #endif
const struct device_type ata_port_type = { const struct device_type ata_port_type = {
...@@ -6105,6 +5343,7 @@ void ata_host_put(struct ata_host *host) ...@@ -6105,6 +5343,7 @@ void ata_host_put(struct ata_host *host)
{ {
kref_put(&host->kref, ata_host_release); kref_put(&host->kref, ata_host_release);
} }
EXPORT_SYMBOL_GPL(ata_host_put);
/** /**
* ata_host_alloc - allocate and init basic ATA host resources * ata_host_alloc - allocate and init basic ATA host resources
...@@ -6178,6 +5417,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) ...@@ -6178,6 +5417,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
kfree(host); kfree(host);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(ata_host_alloc);
/** /**
* ata_host_alloc_pinfo - alloc host and init with port_info array * ata_host_alloc_pinfo - alloc host and init with port_info array
...@@ -6226,68 +5466,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, ...@@ -6226,68 +5466,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
return host; return host;
} }
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;
}
static void ata_host_stop(struct device *gendev, void *res) static void ata_host_stop(struct device *gendev, void *res)
{ {
...@@ -6436,6 +5615,7 @@ int ata_host_start(struct ata_host *host) ...@@ -6436,6 +5615,7 @@ int ata_host_start(struct ata_host *host)
devres_free(start_dr); devres_free(start_dr);
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_host_start);
/** /**
* ata_sas_host_init - Initialize a host struct for sas (ipr, libsas) * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas)
...@@ -6454,6 +5634,7 @@ void ata_host_init(struct ata_host *host, struct device *dev, ...@@ -6454,6 +5634,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
host->ops = ops; host->ops = ops;
kref_init(&host->kref); kref_init(&host->kref);
} }
EXPORT_SYMBOL_GPL(ata_host_init);
void __ata_port_probe(struct ata_port *ap) void __ata_port_probe(struct ata_port *ap)
{ {
...@@ -6609,6 +5790,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ...@@ -6609,6 +5790,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_host_register);
/** /**
* ata_host_activate - start host, request IRQ and register it * ata_host_activate - start host, request IRQ and register it
...@@ -6671,6 +5853,7 @@ int ata_host_activate(struct ata_host *host, int irq, ...@@ -6671,6 +5853,7 @@ int ata_host_activate(struct ata_host *host, int irq,
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_host_activate);
/** /**
* ata_port_detach - Detach ATA port in preparation of device removal * ata_port_detach - Detach ATA port in preparation of device removal
...@@ -6746,6 +5929,7 @@ void ata_host_detach(struct ata_host *host) ...@@ -6746,6 +5929,7 @@ void ata_host_detach(struct ata_host *host)
/* the host is dead now, dissociate ACPI */ /* the host is dead now, dissociate ACPI */
ata_acpi_dissociate(host); ata_acpi_dissociate(host);
} }
EXPORT_SYMBOL_GPL(ata_host_detach);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -6766,6 +5950,7 @@ void ata_pci_remove_one(struct pci_dev *pdev) ...@@ -6766,6 +5950,7 @@ void ata_pci_remove_one(struct pci_dev *pdev)
ata_host_detach(host); ata_host_detach(host);
} }
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
void ata_pci_shutdown_one(struct pci_dev *pdev) void ata_pci_shutdown_one(struct pci_dev *pdev)
{ {
...@@ -6786,6 +5971,7 @@ void ata_pci_shutdown_one(struct pci_dev *pdev) ...@@ -6786,6 +5971,7 @@ void ata_pci_shutdown_one(struct pci_dev *pdev)
ap->ops->port_stop(ap); ap->ops->port_stop(ap);
} }
} }
EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
/* move to PCI subsystem */ /* move to PCI subsystem */
int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
...@@ -6820,6 +6006,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) ...@@ -6820,6 +6006,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
return (tmp == bits->val) ? 1 : 0; return (tmp == bits->val) ? 1 : 0;
} }
EXPORT_SYMBOL_GPL(pci_test_config_bits);
#ifdef CONFIG_PM #ifdef CONFIG_PM
void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
...@@ -6830,6 +6017,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) ...@@ -6830,6 +6017,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
if (mesg.event & PM_EVENT_SLEEP) if (mesg.event & PM_EVENT_SLEEP)
pci_set_power_state(pdev, PCI_D3hot); 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) int ata_pci_device_do_resume(struct pci_dev *pdev)
{ {
...@@ -6848,6 +6036,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev) ...@@ -6848,6 +6036,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev)
pci_set_master(pdev); pci_set_master(pdev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{ {
...@@ -6862,6 +6051,7 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) ...@@ -6862,6 +6051,7 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
int ata_pci_device_resume(struct pci_dev *pdev) int ata_pci_device_resume(struct pci_dev *pdev)
{ {
...@@ -6873,8 +6063,8 @@ int ata_pci_device_resume(struct pci_dev *pdev) ...@@ -6873,8 +6063,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
ata_host_resume(host); ata_host_resume(host);
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_pci_device_resume);
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
/** /**
...@@ -6896,7 +6086,9 @@ int ata_platform_remove_one(struct platform_device *pdev) ...@@ -6896,7 +6086,9 @@ int ata_platform_remove_one(struct platform_device *pdev)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_platform_remove_one);
#ifdef CONFIG_ATA_FORCE
static int __init ata_parse_force_one(char **cur, static int __init ata_parse_force_one(char **cur,
struct ata_force_ent *force_ent, struct ata_force_ent *force_ent,
const char **reason) const char **reason)
...@@ -7076,6 +6268,15 @@ static void __init ata_parse_force_param(void) ...@@ -7076,6 +6268,15 @@ static void __init ata_parse_force_param(void)
ata_force_tbl_size = idx; ata_force_tbl_size = idx;
} }
static void ata_free_force_param(void)
{
kfree(ata_force_tbl);
}
#else
static inline void ata_parse_force_param(void) { }
static inline void ata_free_force_param(void) { }
#endif
static int __init ata_init(void) static int __init ata_init(void)
{ {
int rc; int rc;
...@@ -7084,7 +6285,7 @@ static int __init ata_init(void) ...@@ -7084,7 +6285,7 @@ static int __init ata_init(void)
rc = ata_sff_init(); rc = ata_sff_init();
if (rc) { if (rc) {
kfree(ata_force_tbl); ata_free_force_param();
return rc; return rc;
} }
...@@ -7108,7 +6309,7 @@ static void __exit ata_exit(void) ...@@ -7108,7 +6309,7 @@ static void __exit ata_exit(void)
ata_release_transport(ata_scsi_transport_template); ata_release_transport(ata_scsi_transport_template);
libata_transport_exit(); libata_transport_exit();
ata_sff_exit(); ata_sff_exit();
kfree(ata_force_tbl); ata_free_force_param();
} }
subsys_initcall(ata_init); subsys_initcall(ata_init);
...@@ -7120,6 +6321,7 @@ int ata_ratelimit(void) ...@@ -7120,6 +6321,7 @@ int ata_ratelimit(void)
{ {
return __ratelimit(&ratelimit); return __ratelimit(&ratelimit);
} }
EXPORT_SYMBOL_GPL(ata_ratelimit);
/** /**
* ata_msleep - ATA EH owner aware msleep * ata_msleep - ATA EH owner aware msleep
...@@ -7152,6 +6354,7 @@ void ata_msleep(struct ata_port *ap, unsigned int msecs) ...@@ -7152,6 +6354,7 @@ void ata_msleep(struct ata_port *ap, unsigned int msecs)
if (owns_eh) if (owns_eh)
ata_eh_acquire(ap); ata_eh_acquire(ap);
} }
EXPORT_SYMBOL_GPL(ata_msleep);
/** /**
* ata_wait_register - wait until register value changes * ata_wait_register - wait until register value changes
...@@ -7198,38 +6401,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, ...@@ -7198,38 +6401,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
return tmp; return tmp;
} }
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 * Dummy port_ops
...@@ -7251,10 +6423,12 @@ struct ata_port_operations ata_dummy_port_ops = { ...@@ -7251,10 +6423,12 @@ struct ata_port_operations ata_dummy_port_ops = {
.sched_eh = ata_std_sched_eh, .sched_eh = ata_std_sched_eh,
.end_eh = ata_std_end_eh, .end_eh = ata_std_end_eh,
}; };
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
const struct ata_port_info ata_dummy_port_info = { const struct ata_port_info ata_dummy_port_info = {
.port_ops = &ata_dummy_port_ops, .port_ops = &ata_dummy_port_ops,
}; };
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
/* /*
* Utility print functions * Utility print functions
...@@ -7322,127 +6496,3 @@ void ata_print_version(const struct device *dev, const char *version) ...@@ -7322,127 +6496,3 @@ void ata_print_version(const struct device *dev, const char *version)
dev_printk(KERN_DEBUG, dev, "version %s\n", version); dev_printk(KERN_DEBUG, dev, "version %s\n", version);
} }
EXPORT_SYMBOL(ata_print_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_shutdown_one);
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);
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-eh.c - libata error handling * 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> * Copyright 2006 Tejun Heo <htejun@gmail.com>
* *
* libata documentation is available via 'make {ps|pdf}docs', * libata documentation is available via 'make {ps|pdf}docs',
...@@ -184,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) ...@@ -184,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
__ata_ehi_pushv_desc(ehi, fmt, args); __ata_ehi_pushv_desc(ehi, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
/** /**
* ata_ehi_push_desc - push error description with separator * ata_ehi_push_desc - push error description with separator
...@@ -207,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) ...@@ -207,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
__ata_ehi_pushv_desc(ehi, fmt, args); __ata_ehi_pushv_desc(ehi, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
/** /**
* ata_ehi_clear_desc - clean error description * ata_ehi_clear_desc - clean error description
...@@ -222,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi) ...@@ -222,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
ehi->desc[0] = '\0'; ehi->desc[0] = '\0';
ehi->desc_len = 0; ehi->desc_len = 0;
} }
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
/** /**
* ata_port_desc - append port description * ata_port_desc - append port description
...@@ -249,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...) ...@@ -249,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
__ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(ata_port_desc);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/** /**
* ata_port_pbar_desc - append PCI BAR description * ata_port_pbar_desc - append PCI BAR description
* @ap: target ATA port * @ap: target ATA port
...@@ -288,7 +287,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, ...@@ -288,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, ata_port_desc(ap, "%s 0x%llx", name,
start + (unsigned long long)offset); start + (unsigned long long)offset);
} }
EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
static int ata_lookup_timeout_table(u8 cmd) static int ata_lookup_timeout_table(u8 cmd)
...@@ -973,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap) ...@@ -973,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap)
/* see: ata_std_sched_eh, unless you know better */ /* see: ata_std_sched_eh, unless you know better */
ap->ops->sched_eh(ap); 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) static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
{ {
...@@ -1015,6 +1015,7 @@ int ata_link_abort(struct ata_link *link) ...@@ -1015,6 +1015,7 @@ int ata_link_abort(struct ata_link *link)
{ {
return ata_do_link_abort(link->ap, 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 * ata_port_abort - abort all qc's on the port
...@@ -1032,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap) ...@@ -1032,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap)
{ {
return ata_do_link_abort(ap, NULL); return ata_do_link_abort(ap, NULL);
} }
EXPORT_SYMBOL_GPL(ata_port_abort);
/** /**
* __ata_port_freeze - freeze port * __ata_port_freeze - freeze port
...@@ -1088,79 +1090,7 @@ int ata_port_freeze(struct ata_port *ap) ...@@ -1088,79 +1090,7 @@ int ata_port_freeze(struct ata_port *ap)
return nr_aborted; return nr_aborted;
} }
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;
}
}
/** /**
* ata_eh_freeze_port - EH helper to freeze port * ata_eh_freeze_port - EH helper to freeze port
...@@ -1182,6 +1112,7 @@ void ata_eh_freeze_port(struct ata_port *ap) ...@@ -1182,6 +1112,7 @@ void ata_eh_freeze_port(struct ata_port *ap)
__ata_port_freeze(ap); __ata_port_freeze(ap);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
} }
EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
/** /**
* ata_port_thaw_port - EH helper to thaw port * ata_port_thaw_port - EH helper to thaw port
...@@ -1289,6 +1220,7 @@ void ata_dev_disable(struct ata_device *dev) ...@@ -1289,6 +1220,7 @@ void ata_dev_disable(struct ata_device *dev)
*/ */
ata_ering_clear(&dev->ering); ata_ering_clear(&dev->ering);
} }
EXPORT_SYMBOL_GPL(ata_dev_disable);
/** /**
* ata_eh_detach_dev - detach ATA device * ata_eh_detach_dev - detach ATA device
...@@ -1419,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask) ...@@ -1419,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask)
return "unknown error"; 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 * atapi_eh_tur - perform ATAPI TEST_UNIT_READY
* @dev: target ATAPI device * @dev: target ATAPI device
...@@ -1658,80 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link) ...@@ -1658,80 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link)
ehc->i.action |= action; 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;
}
/** /**
* ata_eh_analyze_tf - analyze taskfile of a failed qc * ata_eh_analyze_tf - analyze taskfile of a failed qc
* @qc: qc to analyze * @qc: qc to analyze
...@@ -3436,7 +3238,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, ...@@ -3436,7 +3238,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
int rc; int rc;
/* if the link or host doesn't do LPM, noop */ /* if the link or host doesn't do LPM, noop */
if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) if (!IS_ENABLED(CONFIG_SATA_HOST) ||
(link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))
return 0; return 0;
/* /*
...@@ -4052,6 +3855,7 @@ void ata_std_error_handler(struct ata_port *ap) ...@@ -4052,6 +3855,7 @@ void ata_std_error_handler(struct ata_port *ap)
ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
} }
EXPORT_SYMBOL_GPL(ata_std_error_handler);
#ifdef CONFIG_PM #ifdef CONFIG_PM
/** /**
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* 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.
*/
s = ata_timing_find_mode(speed);
if (!s)
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);
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* SATA specific part of ATA helper library
*
* Copyright 2003-2004 Red Hat, Inc. All rights reserved.
* Copyright 2003-2004 Jeff Garzik
* Copyright 2006 Tejun Heo <htejun@gmail.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <linux/libata.h>
#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);
/**
* 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_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_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
* @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);
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);
/**
* 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_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_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);
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);
/**
* 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);
}
/**
* 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_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);
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-scsi.c - helper library for ATA * 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 Red Hat, Inc. All rights reserved.
* Copyright 2003-2004 Jeff Garzik * Copyright 2003-2004 Jeff Garzik
* *
...@@ -36,11 +32,12 @@ ...@@ -36,11 +32,12 @@
#include <linux/suspend.h> #include <linux/suspend.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/ioprio.h> #include <linux/ioprio.h>
#include <linux/of.h>
#include "libata.h" #include "libata.h"
#include "libata-transport.h" #include "libata-transport.h"
#define ATA_SCSI_RBUF_SIZE 4096 #define ATA_SCSI_RBUF_SIZE 576
static DEFINE_SPINLOCK(ata_scsi_rbuf_lock); static DEFINE_SPINLOCK(ata_scsi_rbuf_lock);
static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE]; static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
...@@ -49,8 +46,6 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); ...@@ -49,8 +46,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, static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev); 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 0x1
#define RW_RECOVERY_MPAGE_LEN 12 #define RW_RECOVERY_MPAGE_LEN 12
...@@ -90,71 +85,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { ...@@ -90,71 +85,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
0, 30 /* extended self test time, see 05-359r1 */ 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, static ssize_t ata_scsi_park_show(struct device *device,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -258,83 +188,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ...@@ -258,83 +188,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store); ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads); 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, void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
u8 sk, u8 asc, u8 ascq) u8 sk, u8 asc, u8 ascq)
{ {
...@@ -383,90 +236,8 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, ...@@ -383,90 +236,8 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev,
field, 0xff, 0); 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[] = { struct device_attribute *ata_common_sdev_attrs[] = {
&dev_attr_unload_heads, &dev_attr_unload_heads,
&dev_attr_ncq_prio_enable,
NULL NULL
}; };
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
...@@ -499,6 +270,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, ...@@ -499,6 +270,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ata_std_bios_param);
/** /**
* ata_scsi_unlock_native_capacity - unlock native capacity * ata_scsi_unlock_native_capacity - unlock native capacity
...@@ -528,6 +300,7 @@ void ata_scsi_unlock_native_capacity(struct scsi_device *sdev) ...@@ -528,6 +300,7 @@ void ata_scsi_unlock_native_capacity(struct scsi_device *sdev)
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
ata_port_wait_eh(ap); ata_port_wait_eh(ap);
} }
EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
/** /**
* ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
...@@ -1215,7 +988,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) ...@@ -1215,7 +988,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block); 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_rw = 1;
sdev->use_10_for_ms = 1; sdev->use_10_for_ms = 1;
...@@ -1255,8 +1028,7 @@ static int atapi_drain_needed(struct request *rq) ...@@ -1255,8 +1028,7 @@ static int atapi_drain_needed(struct request *rq)
return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC; return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC;
} }
static int ata_scsi_dev_config(struct scsi_device *sdev, int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
struct ata_device *dev)
{ {
struct request_queue *q = sdev->request_queue; struct request_queue *q = sdev->request_queue;
...@@ -1344,6 +1116,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ...@@ -1344,6 +1116,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
/** /**
* ata_scsi_slave_destroy - SCSI device is about to be destroyed * ata_scsi_slave_destroy - SCSI device is about to be destroyed
...@@ -1383,71 +1156,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) ...@@ -1383,71 +1156,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
q->dma_drain_buffer = NULL; q->dma_drain_buffer = NULL;
q->dma_drain_size = 0; q->dma_drain_size = 0;
} }
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);
}
/**
* 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);
}
/** /**
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
...@@ -2354,10 +2063,6 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2354,10 +2063,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) 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[1] = 0x89; /* our page code */
rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */ rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */
rbuf[3] = (0x238 & 0xff); rbuf[3] = (0x238 & 0xff);
...@@ -2366,14 +2071,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2366,14 +2071,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
memcpy(&rbuf[16], "libata ", 16); memcpy(&rbuf[16], "libata ", 16);
memcpy(&rbuf[32], DRV_VERSION, 4); 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[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; rbuf[56] = ATA_CMD_ID_ATA;
...@@ -3089,7 +2794,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, ...@@ -3089,7 +2794,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
* RETURNS: * RETURNS:
* Associated ATA device, or %NULL if not found. * 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) ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
{ {
struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
...@@ -4299,8 +4004,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) ...@@ -4299,8 +4004,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(). * Prints the contents of a SCSI command via printk().
*/ */
static inline void ata_scsi_dump_cdb(struct ata_port *ap, void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd)
struct scsi_cmnd *cmd)
{ {
#ifdef ATA_VERBOSE_DEBUG #ifdef ATA_VERBOSE_DEBUG
struct scsi_device *scsidev = cmd->device; struct scsi_device *scsidev = cmd->device;
...@@ -4312,8 +4016,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, ...@@ -4312,8 +4016,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
#endif #endif
} }
static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
struct ata_device *dev)
{ {
u8 scsi_op = scmd->cmnd[0]; u8 scsi_op = scmd->cmnd[0];
ata_xlat_func_t xlat_func; ata_xlat_func_t xlat_func;
...@@ -4407,6 +4110,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) ...@@ -4407,6 +4110,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
/** /**
* ata_scsi_simulate - simulate SCSI command on ATA device * ata_scsi_simulate - simulate SCSI command on ATA device
...@@ -4562,26 +4266,51 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) ...@@ -4562,26 +4266,51 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
*/ */
shost->max_host_blocked = 1; shost->max_host_blocked = 1;
rc = scsi_add_host_with_dma(ap->scsi_host, rc = scsi_add_host_with_dma(shost, &ap->tdev, ap->host->dev);
&ap->tdev, ap->host->dev);
if (rc) if (rc)
goto err_add; goto err_alloc;
} }
return 0; return 0;
err_add:
scsi_host_put(host->ports[i]->scsi_host);
err_alloc: err_alloc:
while (--i >= 0) { while (--i >= 0) {
struct Scsi_Host *shost = host->ports[i]->scsi_host; struct Scsi_Host *shost = host->ports[i]->scsi_host;
/* scsi_host_put() is in ata_devres_release() */
scsi_remove_host(shost); scsi_remove_host(shost);
scsi_host_put(shost);
} }
return rc; return rc;
} }
#ifdef CONFIG_OF
static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap)
{
struct scsi_device *sdev = dev->sdev;
struct device *d = ap->host->dev;
struct device_node *np = d->of_node;
struct device_node *child;
for_each_available_child_of_node(np, child) {
int ret;
u32 val;
ret = of_property_read_u32(child, "reg", &val);
if (ret)
continue;
if (val == dev->devno) {
dev_dbg(d, "found matching device node\n");
sdev->sdev_gendev.of_node = child;
return;
}
}
}
#else
static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap)
{
}
#endif
void ata_scsi_scan_host(struct ata_port *ap, int sync) void ata_scsi_scan_host(struct ata_port *ap, int sync)
{ {
int tries = 5; int tries = 5;
...@@ -4607,6 +4336,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) ...@@ -4607,6 +4336,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
NULL); NULL);
if (!IS_ERR(sdev)) { if (!IS_ERR(sdev)) {
dev->sdev = sdev; dev->sdev = sdev;
ata_scsi_assign_ofnode(dev, ap);
scsi_device_put(sdev); scsi_device_put(sdev);
} else { } else {
dev->sdev = NULL; dev->sdev = NULL;
...@@ -4929,214 +4659,3 @@ void ata_scsi_dev_rescan(struct work_struct *work) ...@@ -4929,214 +4659,3 @@ void ata_scsi_dev_rescan(struct work_struct *work)
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
mutex_unlock(&ap->scsi_scan_mutex); 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);
}
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-sff.c - helper library for PCI IDE BMDMA * 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 Red Hat, Inc. All rights reserved.
* Copyright 2003-2006 Jeff Garzik * Copyright 2003-2006 Jeff Garzik
* *
......
...@@ -208,7 +208,7 @@ show_ata_port_##name(struct device *dev, \ ...@@ -208,7 +208,7 @@ show_ata_port_##name(struct device *dev, \
{ \ { \
struct ata_port *ap = transport_class_to_port(dev); \ struct ata_port *ap = transport_class_to_port(dev); \
\ \
return snprintf(buf, 20, format_string, cast ap->field); \ return scnprintf(buf, 20, format_string, cast ap->field); \
} }
#define ata_port_simple_attr(field, name, format_string, type) \ #define ata_port_simple_attr(field, name, format_string, type) \
...@@ -479,7 +479,7 @@ show_ata_dev_##field(struct device *dev, \ ...@@ -479,7 +479,7 @@ show_ata_dev_##field(struct device *dev, \
{ \ { \
struct ata_device *ata_dev = transport_class_to_dev(dev); \ struct ata_device *ata_dev = transport_class_to_dev(dev); \
\ \
return snprintf(buf, 20, format_string, cast ata_dev->field); \ return scnprintf(buf, 20, format_string, cast ata_dev->field); \
} }
#define ata_dev_simple_attr(field, format_string, type) \ #define ata_dev_simple_attr(field, format_string, type) \
...@@ -533,7 +533,7 @@ show_ata_dev_id(struct device *dev, ...@@ -533,7 +533,7 @@ show_ata_dev_id(struct device *dev,
if (ata_dev->class == ATA_DEV_PMP) if (ata_dev->class == ATA_DEV_PMP)
return 0; return 0;
for(i=0;i<ATA_ID_WORDS;i++) { for(i=0;i<ATA_ID_WORDS;i++) {
written += snprintf(buf+written, 20, "%04x%c", written += scnprintf(buf+written, 20, "%04x%c",
ata_dev->id[i], ata_dev->id[i],
((i+1) & 7) ? ' ' : '\n'); ((i+1) & 7) ? ' ' : '\n');
} }
...@@ -552,7 +552,7 @@ show_ata_dev_gscr(struct device *dev, ...@@ -552,7 +552,7 @@ show_ata_dev_gscr(struct device *dev,
if (ata_dev->class != ATA_DEV_PMP) if (ata_dev->class != ATA_DEV_PMP)
return 0; return 0;
for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) { for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
written += snprintf(buf+written, 20, "%08x%c", written += scnprintf(buf+written, 20, "%08x%c",
ata_dev->gscr[i], ata_dev->gscr[i],
((i+1) & 3) ? ' ' : '\n'); ((i+1) & 3) ? ' ' : '\n');
} }
...@@ -581,7 +581,7 @@ show_ata_dev_trim(struct device *dev, ...@@ -581,7 +581,7 @@ show_ata_dev_trim(struct device *dev,
else else
mode = "unqueued"; mode = "unqueued";
return snprintf(buf, 20, "%s\n", mode); return scnprintf(buf, 20, "%s\n", mode);
} }
static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL); static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL);
......
...@@ -37,7 +37,11 @@ extern int libata_noacpi; ...@@ -37,7 +37,11 @@ extern int libata_noacpi;
extern int libata_allow_tpm; extern int libata_allow_tpm;
extern const struct device_type ata_port_type; extern const struct device_type ata_port_type;
extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
#ifdef CONFIG_ATA_FORCE
extern void ata_force_cbl(struct ata_port *ap); extern void ata_force_cbl(struct ata_port *ap);
#else
static inline void ata_force_cbl(struct ata_port *ap) { }
#endif
extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
...@@ -87,6 +91,18 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, ...@@ -87,6 +91,18 @@ 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) #define to_ata_port(d) container_of(d, struct ata_port, tdev)
/* libata-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-acpi.c */ /* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
extern unsigned int ata_acpi_gtf_filter; extern unsigned int ata_acpi_gtf_filter;
...@@ -112,6 +128,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} ...@@ -112,6 +128,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
#endif #endif
/* libata-scsi.c */ /* 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, extern int ata_scsi_add_hosts(struct ata_host *host,
struct scsi_host_template *sht); struct scsi_host_template *sht);
extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
...@@ -128,9 +146,10 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); ...@@ -128,9 +146,10 @@ extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap); extern int ata_bus_probe(struct ata_port *ap);
extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, u64 lun); unsigned int id, u64 lun);
int ata_sas_allocate_tag(struct ata_port *ap); void ata_scsi_sdev_config(struct scsi_device *sdev);
void ata_sas_free_tag(unsigned int tag, struct ata_port *ap); 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-eh.c */ /* libata-eh.c */
extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
......
...@@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, ...@@ -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_error_handler(struct ata_port *ap);
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
static int pdc_pata_cable_detect(struct ata_port *ap); 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 = { static struct scsi_host_template pdc_ata_sht = {
ATA_BASE_SHT(DRV_NAME), ATA_BASE_SHT(DRV_NAME),
...@@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = { ...@@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = {
static struct ata_port_operations pdc_sata_ops = { static struct ata_port_operations pdc_sata_ops = {
.inherits = &pdc_common_ops, .inherits = &pdc_common_ops,
.cable_detect = pdc_sata_cable_detect, .cable_detect = ata_cable_sata,
.freeze = pdc_sata_freeze, .freeze = pdc_sata_freeze,
.thaw = pdc_sata_thaw, .thaw = pdc_sata_thaw,
.scr_read = pdc_sata_scr_read, .scr_read = pdc_sata_scr_read,
...@@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap) ...@@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap)
return ATA_CBL_PATA80; 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, static int pdc_sata_scr_read(struct ata_link *link,
unsigned int sc_reg, u32 *val) unsigned int sc_reg, u32 *val)
{ {
......
...@@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO ...@@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO
config SCSI_IPR config SCSI_IPR
tristate "IBM Power Linux RAID adapter support" tristate "IBM Power Linux RAID adapter support"
depends on PCI && SCSI && ATA depends on PCI && SCSI && ATA
select SATA_HOST
select FW_LOADER select FW_LOADER
select IRQ_POLL select IRQ_POLL
select SGL_ALLOC select SGL_ALLOC
......
...@@ -19,6 +19,7 @@ config SCSI_SAS_ATA ...@@ -19,6 +19,7 @@ config SCSI_SAS_ATA
bool "ATA support for libsas (requires libata)" bool "ATA support for libsas (requires libata)"
depends on SCSI_SAS_LIBSAS depends on SCSI_SAS_LIBSAS
depends on ATA = y || ATA = SCSI_SAS_LIBSAS depends on ATA = y || ATA = SCSI_SAS_LIBSAS
select SATA_HOST
help help
Builds in ATA support into libsas. Will necessitate Builds in ATA support into libsas. Will necessitate
the loading of libata along with libsas. the loading of libata along with libsas.
......
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
#define VPRINTK(fmt, args...) #define VPRINTK(fmt, args...)
#endif /* ATA_DEBUG */ #endif /* ATA_DEBUG */
#define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
#define ata_print_version_once(dev, version) \ #define ata_print_version_once(dev, version) \
({ \ ({ \
static bool __print_once; \ static bool __print_once; \
...@@ -176,6 +174,7 @@ enum { ...@@ -176,6 +174,7 @@ enum {
ATA_DEV_NONE = 11, /* no device */ ATA_DEV_NONE = 11, /* no device */
/* struct ata_link flags */ /* 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_HRST = (1 << 1), /* avoid hardreset */
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */ ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */ ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
...@@ -531,12 +530,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes, ...@@ -531,12 +530,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
unsigned long deadline); unsigned long deadline);
typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); 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; 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_ncq_prio_enable;
extern struct device_attribute dev_attr_em_message_type; extern struct device_attribute dev_attr_em_message_type;
extern struct device_attribute dev_attr_em_message; extern struct device_attribute dev_attr_em_message;
extern struct device_attribute dev_attr_sw_activity; extern struct device_attribute dev_attr_sw_activity;
#endif
enum sw_activity { enum sw_activity {
OFF, OFF,
...@@ -1020,10 +1021,6 @@ struct ata_timing { ...@@ -1020,10 +1021,6 @@ struct ata_timing {
/* /*
* Core layer - drivers/ata/libata-core.c * 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 struct ata_port_operations ata_dummy_port_ops;
extern const struct ata_port_info ata_dummy_port_info; extern const struct ata_port_info ata_dummy_port_info;
...@@ -1061,33 +1058,14 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf) ...@@ -1061,33 +1058,14 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf)
(tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); (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) static inline int ata_port_is_dummy(struct ata_port *ap)
{ {
return ap->ops == &ata_dummy_port_ops; 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_std_prereset(struct ata_link *link, unsigned long deadline);
extern int ata_wait_after_reset(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)); 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_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 sata_std_hardreset(struct ata_link *link, unsigned int *class, extern int sata_std_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline); unsigned long deadline);
extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
...@@ -1095,7 +1073,6 @@ extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); ...@@ -1095,7 +1073,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(struct device *dev, int max_ports);
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev, extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
const struct ata_port_info * const * ppi, int n_ports); 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_get(struct ata_host *host);
extern void ata_host_put(struct ata_host *host); extern void ata_host_put(struct ata_host *host);
extern int ata_host_start(struct ata_host *host); extern int ata_host_start(struct ata_host *host);
...@@ -1117,22 +1094,6 @@ extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd, ...@@ -1117,22 +1094,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_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
unsigned int cmd, void __user *arg); 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 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_online(struct ata_link *link);
extern bool ata_link_offline(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link);
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1153,9 +1114,6 @@ extern void ata_msleep(struct ata_port *ap, unsigned int msecs); ...@@ -1153,9 +1114,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, extern u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask,
u32 val, unsigned long interval, unsigned long timeout); u32 val, unsigned long interval, unsigned long timeout);
extern int atapi_cmd_type(u8 opcode); 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, extern unsigned long ata_pack_xfermask(unsigned long pio_mask,
unsigned long mwdma_mask, unsigned long udma_mask); unsigned long mwdma_mask, unsigned long udma_mask);
extern void ata_unpack_xfermask(unsigned long xfer_mask, extern void ata_unpack_xfermask(unsigned long xfer_mask,
...@@ -1179,7 +1137,6 @@ extern void ata_id_c_string(const u16 *id, unsigned char *s, ...@@ -1179,7 +1137,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, extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id); struct ata_taskfile *tf, u16 *id);
extern void ata_qc_complete(struct ata_queued_cmd *qc); 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 u64 ata_qc_get_active(struct ata_port *ap);
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd);
extern int ata_std_bios_param(struct scsi_device *sdev, extern int ata_std_bios_param(struct scsi_device *sdev,
...@@ -1196,7 +1153,96 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev); ...@@ -1196,7 +1153,96 @@ 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 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_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); extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q);
/*
* SATA specific code - drivers/ata/libata-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_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 int sata_set_spd(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_link_resume(struct ata_link *link, const unsigned long *params,
unsigned long deadline);
extern void ata_eh_analyze_ncq_error(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_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;
}
static inline int sata_set_spd(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;
}
static inline int sata_link_resume(struct ata_link *link,
const unsigned long *params,
unsigned long deadline)
{
return -EOPNOTSUPP;
}
static inline void ata_eh_analyze_ncq_error(struct ata_link *link) { }
#endif
extern int sata_link_debounce(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);
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 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); extern bool sata_lpm_ignore_phy_events(struct ata_link *link);
extern int sata_async_notification(struct ata_port *ap);
extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_40wire(struct ata_port *ap);
extern int ata_cable_80wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap);
...@@ -1206,12 +1252,6 @@ extern int ata_cable_unknown(struct ata_port *ap); ...@@ -1206,12 +1252,6 @@ extern int ata_cable_unknown(struct ata_port *ap);
/* Timing helpers */ /* Timing helpers */
extern unsigned int ata_pio_need_iordy(const struct ata_device *); 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);
extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle);
/* PCI */ /* PCI */
...@@ -1295,14 +1335,12 @@ extern void ata_port_wait_eh(struct ata_port *ap); ...@@ -1295,14 +1335,12 @@ extern void ata_port_wait_eh(struct ata_port *ap);
extern int ata_link_abort(struct ata_link *link); extern int ata_link_abort(struct ata_link *link);
extern int ata_port_abort(struct ata_port *ap); extern int ata_port_abort(struct ata_port *ap);
extern int ata_port_freeze(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_freeze_port(struct ata_port *ap);
extern void ata_eh_thaw_port(struct ata_port *ap); 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_complete(struct ata_queued_cmd *qc);
extern void ata_eh_qc_retry(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, extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
...@@ -1343,7 +1381,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; ...@@ -1343,7 +1381,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
* edge driver's module reference, otherwise the driver can be unloaded * edge driver's module reference, otherwise the driver can be unloaded
* even if the scsi_device is being accessed. * even if the scsi_device is being accessed.
*/ */
#define ATA_BASE_SHT(drv_name) \ #define __ATA_BASE_SHT(drv_name) \
.module = THIS_MODULE, \ .module = THIS_MODULE, \
.name = drv_name, \ .name = drv_name, \
.ioctl = ata_scsi_ioctl, \ .ioctl = ata_scsi_ioctl, \
...@@ -1357,12 +1395,20 @@ extern struct device_attribute *ata_common_sdev_attrs[]; ...@@ -1357,12 +1395,20 @@ extern struct device_attribute *ata_common_sdev_attrs[];
.slave_configure = ata_scsi_slave_config, \ .slave_configure = ata_scsi_slave_config, \
.slave_destroy = ata_scsi_slave_destroy, \ .slave_destroy = ata_scsi_slave_destroy, \
.bios_param = ata_std_bios_param, \ .bios_param = ata_std_bios_param, \
.unlock_native_capacity = ata_scsi_unlock_native_capacity, \ .unlock_native_capacity = ata_scsi_unlock_native_capacity
#define ATA_BASE_SHT(drv_name) \
__ATA_BASE_SHT(drv_name), \
.sdev_attrs = ata_common_sdev_attrs .sdev_attrs = ata_common_sdev_attrs
#ifdef CONFIG_SATA_HOST
extern struct device_attribute *ata_ncq_sdev_attrs[];
#define ATA_NCQ_SHT(drv_name) \ #define ATA_NCQ_SHT(drv_name) \
ATA_BASE_SHT(drv_name), \ __ATA_BASE_SHT(drv_name), \
.sdev_attrs = ata_ncq_sdev_attrs, \
.change_queue_depth = ata_scsi_change_queue_depth .change_queue_depth = ata_scsi_change_queue_depth
#endif
/* /*
* PMP helpers * PMP helpers
...@@ -1635,6 +1681,8 @@ extern struct ata_device *ata_dev_next(struct ata_device *dev, ...@@ -1635,6 +1681,8 @@ extern struct ata_device *ata_dev_next(struct ata_device *dev,
*/ */
static inline int ata_ncq_enabled(struct ata_device *dev) static inline int ata_ncq_enabled(struct ata_device *dev)
{ {
if (!IS_ENABLED(CONFIG_SATA_HOST))
return 0;
return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ;
} }
...@@ -1803,6 +1851,16 @@ static inline int ata_dma_enabled(struct ata_device *adev) ...@@ -1803,6 +1851,16 @@ static inline int ata_dma_enabled(struct ata_device *adev)
return (adev->dma_mode == 0xFF ? 0 : 1); return (adev->dma_mode == 0xFF ? 0 : 1);
} }
/**************************************************************************
* PATA timings - drivers/ata/libata-pata-timings.c
*/
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);
/************************************************************************** /**************************************************************************
* PMP - drivers/ata/libata-pmp.c * PMP - drivers/ata/libata-pmp.c
*/ */
......
...@@ -148,6 +148,8 @@ ...@@ -148,6 +148,8 @@
/* Vendors and devices. Sort key: vendor first, device next. */ /* Vendors and devices. Sort key: vendor first, device next. */
#define PCI_VENDOR_ID_LOONGSON 0x0014
#define PCI_VENDOR_ID_TTTECH 0x0357 #define PCI_VENDOR_ID_TTTECH 0x0357
#define PCI_DEVICE_ID_TTTECH_MC322 0x000a #define PCI_DEVICE_ID_TTTECH_MC322 0x000a
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment