Merge tag 'for-5.7/libata-2020-03-29' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Mar 2020 18:10:08 +0000 (11:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Mar 2020 18:10:08 +0000 (11:10 -0700)
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
  ...

16 files changed:
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-pata-timings.c [new file with mode: 0644]
drivers/ata/libata-sata.c [new file with mode: 0644]
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata-transport.c
drivers/ata/libata.h
drivers/ata/sata_promise.c
drivers/scsi/Kconfig
drivers/scsi/libsas/Kconfig
include/linux/libata.h
include/linux/pci_ids.h

index a6beb2c5a6920e33b643d853ef4d56caf71e87b8..05ecdce1b702cf8bf6318c6ae5c4dca770cc8229 100644 (file)
@@ -34,6 +34,12 @@ if ATA
 config ATA_NONSTANDARD
        bool
 
+config SATA_HOST
+       bool
+
+config PATA_TIMINGS
+       bool
+
 config ATA_VERBOSE_ERROR
        bool "Verbose ATA error reporting"
        default y
@@ -45,9 +51,26 @@ config ATA_VERBOSE_ERROR
 
          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
        bool "ATA ACPI Support"
        depends on ACPI
+       select PATA_TIMINGS
        default y
        help
          This option adds support for ATA-related ACPI objects.
@@ -73,6 +96,7 @@ config SATA_ZPODD
 
 config SATA_PMP
        bool "SATA Port Multiplier support"
+       depends on SATA_HOST
        default y
        help
          This option adds support for SATA Port Multipliers
@@ -85,6 +109,7 @@ comment "Controllers with non-SFF native interface"
 config SATA_AHCI
        tristate "AHCI SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for AHCI Serial ATA.
 
@@ -111,6 +136,7 @@ config SATA_MOBILE_LPM_POLICY
 
 config SATA_AHCI_PLATFORM
        tristate "Platform AHCI SATA support"
+       select SATA_HOST
        help
          This option enables support for Platform AHCI Serial ATA
          controllers.
@@ -121,6 +147,7 @@ config AHCI_BRCM
        tristate "Broadcom AHCI SATA support"
        depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \
                   ARCH_BCM_63XX
+       select SATA_HOST
        help
          This option enables support for the AHCI SATA3 controller found on
          Broadcom SoC's.
@@ -130,6 +157,7 @@ config AHCI_BRCM
 config AHCI_DA850
        tristate "DaVinci DA850 AHCI SATA support"
        depends on ARCH_DAVINCI_DA850
+       select SATA_HOST
        help
          This option enables support for the DaVinci DA850 SoC's
          onboard AHCI SATA.
@@ -139,6 +167,7 @@ config AHCI_DA850
 config AHCI_DM816
        tristate "DaVinci DM816 AHCI SATA support"
        depends on ARCH_OMAP2PLUS
+       select SATA_HOST
        help
          This option enables support for the DaVinci DM816 SoC's
          onboard AHCI SATA controller.
@@ -148,6 +177,7 @@ config AHCI_DM816
 config AHCI_ST
        tristate "ST AHCI SATA support"
        depends on ARCH_STI
+       select SATA_HOST
        help
          This option enables support for ST AHCI SATA controller.
 
@@ -157,6 +187,7 @@ config AHCI_IMX
        tristate "Freescale i.MX AHCI SATA support"
        depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
        depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON
+       select SATA_HOST
        help
          This option enables support for the Freescale i.MX SoC's
          onboard AHCI SATA.
@@ -166,6 +197,7 @@ config AHCI_IMX
 config AHCI_CEVA
        tristate "CEVA AHCI SATA support"
        depends on OF
+       select SATA_HOST
        help
          This option enables support for the CEVA AHCI SATA.
          It can be found on the Xilinx Zynq UltraScale+ MPSoC.
@@ -176,6 +208,7 @@ config AHCI_MTK
        tristate "MediaTek AHCI SATA support"
        depends on ARCH_MEDIATEK
        select MFD_SYSCON
+       select SATA_HOST
        help
          This option enables support for the MediaTek SoC's
          onboard AHCI SATA controller.
@@ -185,6 +218,7 @@ config AHCI_MTK
 config AHCI_MVEBU
        tristate "Marvell EBU AHCI SATA support"
        depends on ARCH_MVEBU
+       select SATA_HOST
        help
          This option enables support for the Marvebu EBU SoC's
          onboard AHCI SATA.
@@ -203,6 +237,7 @@ config AHCI_OCTEON
 config AHCI_SUNXI
        tristate "Allwinner sunxi AHCI SATA support"
        depends on ARCH_SUNXI
+       select SATA_HOST
        help
          This option enables support for the Allwinner sunxi SoC's
          onboard AHCI SATA.
@@ -212,6 +247,7 @@ config AHCI_SUNXI
 config AHCI_TEGRA
        tristate "NVIDIA Tegra AHCI SATA support"
        depends on ARCH_TEGRA
+       select SATA_HOST
        help
          This option enables support for the NVIDIA Tegra SoC's
          onboard AHCI SATA.
@@ -221,12 +257,14 @@ config AHCI_TEGRA
 config AHCI_XGENE
        tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
        depends on PHY_XGENE
+       select SATA_HOST
        help
         This option enables support for APM X-Gene SoC SATA host controller.
 
 config AHCI_QORIQ
        tristate "Freescale QorIQ AHCI SATA support"
        depends on OF
+       select SATA_HOST
        help
          This option enables support for the Freescale QorIQ AHCI SoC's
          onboard AHCI SATA.
@@ -236,6 +274,7 @@ config AHCI_QORIQ
 config SATA_FSL
        tristate "Freescale 3.0Gbps SATA support"
        depends on FSL_SOC
+       select SATA_HOST
        help
          This option enables support for Freescale 3.0Gbps SATA controller.
          It can be found on MPC837x and MPC8315.
@@ -245,6 +284,7 @@ config SATA_FSL
 config SATA_GEMINI
        tristate "Gemini SATA bridge support"
        depends on ARCH_GEMINI || COMPILE_TEST
+       select SATA_HOST
        default ARCH_GEMINI
        help
          This enabled support for the FTIDE010 to SATA bridge
@@ -255,6 +295,7 @@ config SATA_GEMINI
 config SATA_AHCI_SEATTLE
        tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support"
        depends on ARCH_SEATTLE
+       select SATA_HOST
        help
         This option enables support for AMD Seattle SATA host controller.
 
@@ -263,12 +304,14 @@ config SATA_AHCI_SEATTLE
 config SATA_INIC162X
        tristate "Initio 162x SATA support (Very Experimental)"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Initio 162x Serial ATA.
 
 config SATA_ACARD_AHCI
        tristate "ACard AHCI variant (ATP 8620)"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Acard.
 
@@ -277,6 +320,7 @@ config SATA_ACARD_AHCI
 config SATA_SIL24
        tristate "Silicon Image 3124/3132 SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Silicon Image 3124/3132 Serial ATA.
 
@@ -317,6 +361,7 @@ config PDC_ADMA
 config PATA_OCTEON_CF
        tristate "OCTEON Boot Bus Compact Flash support"
        depends on CAVIUM_OCTEON_SOC
+       select PATA_TIMINGS
        help
          This option enables a polled compact flash driver for use with
          compact flash cards attached to the OCTEON boot bus.
@@ -326,6 +371,7 @@ config PATA_OCTEON_CF
 config SATA_QSTOR
        tristate "Pacific Digital SATA QStor support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Pacific Digital Serial ATA QStor.
 
@@ -334,6 +380,7 @@ config SATA_QSTOR
 config SATA_SX4
        tristate "Promise SATA SX4 support (Experimental)"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Promise Serial ATA SX4.
 
@@ -357,6 +404,7 @@ comment "SATA SFF controllers with BMDMA"
 config ATA_PIIX
        tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for ICH5/6/7/8 Serial ATA
          and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
@@ -368,6 +416,7 @@ config SATA_DWC
        tristate "DesignWare Cores SATA support"
        depends on DMADEVICES
        select GENERIC_PHY
+       select SATA_HOST
        help
          This option enables support for the on-chip SATA controller of the
          AppliedMicro processor 460EX.
@@ -398,6 +447,7 @@ config SATA_DWC_VDEBUG
 config SATA_HIGHBANK
        tristate "Calxeda Highbank SATA support"
        depends on ARCH_HIGHBANK || COMPILE_TEST
+       select SATA_HOST
        help
          This option enables support for the Calxeda Highbank SoC's
          onboard SATA.
@@ -409,6 +459,7 @@ config SATA_MV
        depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \
                   ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST
        select GENERIC_PHY
+       select SATA_HOST
        help
          This option enables support for the Marvell Serial ATA family.
          Currently supports 88SX[56]0[48][01] PCI(-X) chips,
@@ -419,6 +470,7 @@ config SATA_MV
 config SATA_NV
        tristate "NVIDIA SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for NVIDIA Serial ATA.
 
@@ -427,6 +479,7 @@ config SATA_NV
 config SATA_PROMISE
        tristate "Promise SATA TX2/TX4 support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Promise Serial ATA TX2/TX4.
 
@@ -435,6 +488,7 @@ config SATA_PROMISE
 config SATA_RCAR
        tristate "Renesas R-Car SATA support"
        depends on ARCH_RENESAS || COMPILE_TEST
+       select SATA_HOST
        help
          This option enables support for Renesas R-Car Serial ATA.
 
@@ -443,6 +497,7 @@ config SATA_RCAR
 config SATA_SIL
        tristate "Silicon Image SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Silicon Image Serial ATA.
 
@@ -452,6 +507,7 @@ config SATA_SIS
        tristate "SiS 964/965/966/180 SATA support"
        depends on PCI
        select PATA_SIS
+       select SATA_HOST
        help
          This option enables support for SiS Serial ATA on
          SiS 964/965/966/180 and Parallel ATA on SiS 180.
@@ -462,6 +518,7 @@ config SATA_SIS
 config SATA_SVW
        tristate "ServerWorks Frodo / Apple K2 SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Broadcom/Serverworks/Apple K2
          SATA support.
@@ -471,6 +528,7 @@ config SATA_SVW
 config SATA_ULI
        tristate "ULi Electronics SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for ULi Electronics SATA.
 
@@ -479,6 +537,7 @@ config SATA_ULI
 config SATA_VIA
        tristate "VIA SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for VIA Serial ATA.
 
@@ -487,6 +546,7 @@ config SATA_VIA
 config SATA_VITESSE
        tristate "VITESSE VSC-7174 / INTEL 31244 SATA support"
        depends on PCI
+       select SATA_HOST
        help
          This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA.
 
@@ -497,6 +557,7 @@ comment "PATA SFF controllers with BMDMA"
 config PATA_ALI
        tristate "ALi PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the ALi ATA interfaces
          found on the many ALi chipsets.
@@ -506,6 +567,7 @@ config PATA_ALI
 config PATA_AMD
        tristate "AMD/NVidia PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the AMD and NVidia PATA
          interfaces found on the chipsets for Athlon/Athlon64.
@@ -540,6 +602,7 @@ config PATA_ATIIXP
 config PATA_ATP867X
        tristate "ARTOP/Acard ATP867X PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for ARTOP/Acard ATP867X PATA
          controllers.
@@ -549,6 +612,7 @@ config PATA_ATP867X
 config PATA_BK3710
        tristate "Palmchip BK3710 PATA support"
        depends on ARCH_DAVINCI
+       select PATA_TIMINGS
        help
          This option enables support for the integrated IDE controller on
          the TI DaVinci SoC.
@@ -558,6 +622,7 @@ config PATA_BK3710
 config PATA_CMD64X
        tristate "CMD64x PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the CMD64x series chips
          except for the CMD640.
@@ -603,6 +668,7 @@ config PATA_CS5536
 config PATA_CYPRESS
        tristate "Cypress CY82C693 PATA support (Very Experimental)"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the Cypress/Contaq CY82C693
          chipset found in some Alpha systems
@@ -621,6 +687,7 @@ config PATA_EFAR
 config PATA_EP93XX
        tristate "Cirrus Logic EP93xx PATA support"
        depends on ARCH_EP93XX
+       select PATA_TIMINGS
        help
          This option enables support for the PATA controller in
          the Cirrus Logic EP9312 and EP9315 ARM CPU.
@@ -685,6 +752,7 @@ config PATA_HPT3X3_DMA
 config PATA_ICSIDE
        tristate "Acorn ICS PATA support"
        depends on ARM && ARCH_ACORN
+       select PATA_TIMINGS
        help
          On Acorn systems, say Y here if you wish to use the ICS PATA
          interface card.  This is not required for ICS partition support.
@@ -693,6 +761,7 @@ config PATA_ICSIDE
 config PATA_IMX
        tristate "PATA support for Freescale iMX"
        depends on ARCH_MXC
+       select PATA_TIMINGS
        help
          This option enables support for the PATA host available on Freescale
           iMX SoCs.
@@ -778,6 +847,7 @@ config PATA_NINJA32
 config PATA_NS87415
        tristate "Nat Semi NS87415 PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the National Semiconductor
          NS87415 PCI-IDE controller.
@@ -902,6 +972,7 @@ config PATA_TRIFLEX
 config PATA_VIA
        tristate "VIA PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the VIA PATA interfaces
          found on the many VIA chipsets.
@@ -935,6 +1006,7 @@ comment "PIO-only SFF controllers"
 config PATA_CMD640_PCI
        tristate "CMD640 PCI PATA support (Experimental)"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the CMD640 PCI IDE
          interface chip. Only the primary channel is currently
@@ -1005,6 +1077,7 @@ config PATA_MPIIX
 config PATA_NS87410
        tristate "Nat Semi NS87410 PATA support"
        depends on PCI
+       select PATA_TIMINGS
        help
          This option enables support for the National Semiconductor
          NS87410 PCI-IDE controller.
@@ -1085,6 +1158,7 @@ config PATA_RZ1000
 config PATA_SAMSUNG_CF
        tristate "Samsung SoC PATA support"
        depends on SAMSUNG_DEV_IDE
+       select PATA_TIMINGS
        help
          This option enables basic support for Samsung's S3C/S5P board
          PATA controllers via the new ATA layer
@@ -1104,6 +1178,7 @@ comment "Generic fallback / legacy drivers"
 config PATA_ACPI
        tristate "ACPI firmware driver for PATA"
        depends on ATA_ACPI && ATA_BMDMA && PCI
+       select PATA_TIMINGS
        help
          This option enables an ACPI method driver which drives
          motherboard PATA controller interfaces through the ACPI
@@ -1113,6 +1188,7 @@ config PATA_ACPI
 config ATA_GENERIC
        tristate "Generic ATA support"
        depends on PCI && ATA_BMDMA
+       select SATA_HOST
        help
          This option enables support for generic BIOS configured
          ATA controllers via the new ATA layer
@@ -1122,6 +1198,7 @@ config ATA_GENERIC
 config PATA_LEGACY
        tristate "Legacy ISA PATA support (Experimental)"
        depends on (ISA || PCI)
+       select PATA_TIMINGS
        help
          This option enables support for ISA/VLB/PCI bus legacy PATA
          ports and allows them to be accessed via the new ATA layer.
index d8cc2e04a6c7d032d14794df040948ce7bb5add1..b8aebfb14e825040af4a228b475e0be3c8b028ac 100644 (file)
@@ -123,7 +123,9 @@ obj-$(CONFIG_PATA_LEGACY)   += pata_legacy.o
 
 libata-y       := libata-core.o libata-scsi.o libata-eh.o \
        libata-transport.o libata-trace.o
+libata-$(CONFIG_SATA_HOST)     += libata-sata.o
 libata-$(CONFIG_ATA_SFF)       += libata-sff.o
 libata-$(CONFIG_SATA_PMP)      += libata-pmp.o
 libata-$(CONFIG_ATA_ACPI)      += libata-acpi.o
 libata-$(CONFIG_SATA_ZPODD)    += libata-zpodd.o
+libata-$(CONFIG_PATA_TIMINGS)  += libata-pata-timings.o
index 11ea1aff40dbbabd80daa76d916f3498b41383d8..ad0185c8dcee2c237b07d11eb89f751e075ef285 100644 (file)
@@ -40,6 +40,7 @@
 enum {
        AHCI_PCI_BAR_STA2X11    = 0,
        AHCI_PCI_BAR_CAVIUM     = 0,
+       AHCI_PCI_BAR_LOONGSON   = 0,
        AHCI_PCI_BAR_ENMOTUS    = 2,
        AHCI_PCI_BAR_CAVIUM_GEN5        = 4,
        AHCI_PCI_BAR_STANDARD   = 5,
@@ -245,6 +246,7 @@ static const struct ata_port_info ahci_port_info[] = {
 
 static const struct pci_device_id ahci_pci_tbl[] = {
        /* Intel */
+       { PCI_VDEVICE(INTEL, 0x06d6), board_ahci }, /* Comet Lake PCH-H RAID */
        { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
        { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
        { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
@@ -401,6 +403,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0xa252), 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, 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, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
        { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
@@ -589,6 +593,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        /* Enmotus */
        { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
 
+       /* Loongson */
+       { PCI_VDEVICE(LOONGSON, 0x7a08), board_ahci },
+
        /* Generic, PCI class code for AHCI */
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          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)
                        ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
                if (pdev->device == 0xa084)
                        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 */
index 42c8728f611717f25082edd2a7930451c4f138f6..beca5f91bb4c7c8bed8a40c118717363981da495 100644 (file)
@@ -2,10 +2,6 @@
 /*
  *  libata-core.c - helper library for ATA
  *
- *  Maintained by:  Tejun Heo <tj@kernel.org>
- *                 Please ALWAYS copy linux-ide@vger.kernel.org
- *                 on emails.
- *
  *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2004 Jeff Garzik
  *
  *     http://www.compactflash.org (CF)
  *     http://www.qic.org (QIC157 - Tape and DSC)
  *     http://www.ce-ata.org (CE-ATA: not supported)
+ *
+ * libata is essentially a library of internal helper functions for
+ * low-level ATA host controller drivers.  As such, the API/ABI is
+ * likely to change as new drivers are added and updated.
+ * Do not depend on ABI/API stability.
  */
 
 #include <linux/kernel.h>
@@ -56,6 +57,7 @@
 #include <linux/leds.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
+#include <asm/setup.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/libata.h>
 #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 };
-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 = {
        .prereset               = ata_std_prereset,
        .postreset              = ata_std_postreset,
@@ -82,6 +79,7 @@ const struct ata_port_operations sata_port_ops = {
        .qc_defer               = ata_std_qc_defer,
        .hardreset              = sata_std_hardreset,
 };
+EXPORT_SYMBOL_GPL(sata_port_ops);
 
 static unsigned int ata_dev_init_params(struct ata_device *dev,
                                        u16 heads, u16 sectors);
@@ -91,14 +89,15 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
 atomic_t ata_print_id = ATOMIC_INIT(0);
 
+#ifdef CONFIG_ATA_FORCE
 struct ata_force_param {
        const char      *name;
-       unsigned int    cbl;
-       int             spd_limit;
+       u8              cbl;
+       u8              spd_limit;
        unsigned long   xfer_mask;
        unsigned int    horkage_on;
        unsigned int    horkage_off;
-       unsigned int    lflags;
+       u16             lflags;
 };
 
 struct ata_force_ent {
@@ -110,10 +109,11 @@ struct ata_force_ent {
 static struct ata_force_ent *ata_force_tbl;
 static int ata_force_tbl_size;
 
-static char ata_force_param_buf[PAGE_SIZE] __initdata;
+static char ata_force_param_buf[COMMAND_LINE_SIZE] __initdata;
 /* param_buf is thrown away after initialization, disallow read */
 module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0);
 MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/admin-guide/kernel-parameters.rst for details)");
+#endif
 
 static int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
@@ -224,6 +224,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap,
 
        return NULL;
 }
+EXPORT_SYMBOL_GPL(ata_link_next);
 
 /**
  *     ata_dev_next - device iteration helper
@@ -277,6 +278,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link,
                goto next;
        return dev;
 }
+EXPORT_SYMBOL_GPL(ata_dev_next);
 
 /**
  *     ata_dev_phys_link - find physical link for a device
@@ -303,6 +305,7 @@ struct ata_link *ata_dev_phys_link(struct ata_device *dev)
        return ap->slave_link;
 }
 
+#ifdef CONFIG_ATA_FORCE
 /**
  *     ata_force_cbl - force cable type according to libata.force
  *     @ap: ATA port of interest
@@ -483,6 +486,11 @@ static void ata_force_horkage(struct ata_device *dev)
                               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
@@ -521,79 +529,7 @@ int atapi_cmd_type(u8 opcode)
                return ATAPI_MISC;
        }
 }
-
-/**
- *     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];
-}
+EXPORT_SYMBOL_GPL(atapi_cmd_type);
 
 static const u8 ata_rw_cmds[] = {
        /* pio multi */
@@ -868,6 +804,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask,
                ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
                ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
 }
+EXPORT_SYMBOL_GPL(ata_pack_xfermask);
 
 /**
  *     ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks
@@ -923,6 +860,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask)
                        return ent->base + highbit - ent->shift;
        return 0xff;
 }
+EXPORT_SYMBOL_GPL(ata_xfer_mask2mode);
 
 /**
  *     ata_xfer_mode2mask - Find matching xfer_mask for XFER_*
@@ -946,6 +884,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode)
                                & ~((1 << ent->shift) - 1);
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
 
 /**
  *     ata_xfer_mode2shift - Find matching xfer_shift for XFER_*
@@ -968,6 +907,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode)
                        return ent->shift;
        return -1;
 }
+EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
 
 /**
  *     ata_mode_string - convert xfer_mask to string
@@ -1014,6 +954,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
                return xfer_mode_str[highbit];
        return "<n/a>";
 }
+EXPORT_SYMBOL_GPL(ata_mode_string);
 
 const char *sata_spd_string(unsigned int spd)
 {
@@ -1094,6 +1035,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
        DPRINTK("unknown device\n");
        return ATA_DEV_UNKNOWN;
 }
+EXPORT_SYMBOL_GPL(ata_dev_classify);
 
 /**
  *     ata_id_string - Convert IDENTIFY DEVICE page into string
@@ -1130,6 +1072,7 @@ void ata_id_string(const u16 *id, unsigned char *s,
                len -= 2;
        }
 }
+EXPORT_SYMBOL_GPL(ata_id_string);
 
 /**
  *     ata_id_c_string - Convert IDENTIFY DEVICE page into C string
@@ -1157,6 +1100,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
                p--;
        *p = '\0';
 }
+EXPORT_SYMBOL_GPL(ata_id_c_string);
 
 static u64 ata_id_n_sectors(const u16 *id)
 {
@@ -1514,6 +1458,7 @@ unsigned long ata_id_xfermask(const u16 *id)
 
        return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
 }
+EXPORT_SYMBOL_GPL(ata_id_xfermask);
 
 static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
@@ -1771,6 +1716,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
                return 1;
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
 
 /**
  *     ata_pio_mask_no_iordy   -       Return the non IORDY mask
@@ -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,
                                     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
@@ -2265,6 +2212,8 @@ static int ata_dev_config_ncq(struct ata_device *dev,
                desc[0] = '\0';
                return 0;
        }
+       if (!IS_ENABLED(CONFIG_SATA_HOST))
+               return 0;
        if (dev->horkage & ATA_HORKAGE_NONCQ) {
                snprintf(desc, desc_sz, "NCQ (not used)");
                return 0;
@@ -2783,6 +2732,7 @@ int ata_cable_40wire(struct ata_port *ap)
 {
        return ATA_CBL_PATA40;
 }
+EXPORT_SYMBOL_GPL(ata_cable_40wire);
 
 /**
  *     ata_cable_80wire        -       return 80 wire cable type
@@ -2796,6 +2746,7 @@ int ata_cable_80wire(struct ata_port *ap)
 {
        return ATA_CBL_PATA80;
 }
+EXPORT_SYMBOL_GPL(ata_cable_80wire);
 
 /**
  *     ata_cable_unknown       -       return unknown PATA cable.
@@ -2808,6 +2759,7 @@ int ata_cable_unknown(struct ata_port *ap)
 {
        return ATA_CBL_PATA_UNK;
 }
+EXPORT_SYMBOL_GPL(ata_cable_unknown);
 
 /**
  *     ata_cable_ignore        -       return ignored PATA cable.
@@ -2820,6 +2772,7 @@ int ata_cable_ignore(struct ata_port *ap)
 {
        return ATA_CBL_PATA_IGN;
 }
+EXPORT_SYMBOL_GPL(ata_cable_ignore);
 
 /**
  *     ata_cable_sata  -       return SATA cable type
@@ -2832,6 +2785,7 @@ int ata_cable_sata(struct ata_port *ap)
 {
        return ATA_CBL_SATA;
 }
+EXPORT_SYMBOL_GPL(ata_cable_sata);
 
 /**
  *     ata_bus_probe - Reset and probe ATA bus
@@ -3014,6 +2968,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
                return NULL;
        return pair;
 }
+EXPORT_SYMBOL_GPL(ata_dev_pair);
 
 /**
  *     sata_down_spd_limit - adjust SATA spd limit downward
@@ -3095,252 +3050,7 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
        return 0;
 }
 
-static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
-{
-       struct ata_link *host_link = &link->ap->link;
-       u32 limit, target, spd;
-
-       limit = link->sata_spd_limit;
-
-       /* Don't configure downstream link faster than upstream link.
-        * It doesn't speed up anything and some PMPs choke on such
-        * configuration.
-        */
-       if (!ata_is_host_link(link) && host_link->sata_spd)
-               limit &= (1 << host_link->sata_spd) - 1;
-
-       if (limit == UINT_MAX)
-               target = 0;
-       else
-               target = fls(limit);
-
-       spd = (*scontrol >> 4) & 0xf;
-       *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4);
-
-       return spd != target;
-}
-
-/**
- *     sata_set_spd_needed - is SATA spd configuration needed
- *     @link: Link in question
- *
- *     Test whether the spd limit in SControl matches
- *     @link->sata_spd_limit.  This function is used to determine
- *     whether hardreset is necessary to apply SATA spd
- *     configuration.
- *
- *     LOCKING:
- *     Inherited from caller.
- *
- *     RETURNS:
- *     1 if SATA spd configuration is needed, 0 otherwise.
- */
-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;
-}
-
+#ifdef CONFIG_ATA_ACPI
 /**
  *     ata_timing_cycle2mode - find xfer mode for the specified cycle duration
  *     @xfer_shift: ATA_SHIFT_* value for transfer type to examine.
@@ -3391,6 +3101,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle)
 
        return last_mode;
 }
+#endif
 
 /**
  *     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)
                *r_failed_dev = dev;
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_do_set_mode);
 
 /**
  *     ata_wait_ready - wait for link to become ready
@@ -3771,216 +3483,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
 
        return ata_wait_ready(link, deadline, check_ready);
 }
-
-/**
- *     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;
-       }
-}
-
-/**
- *     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;
-}
-
-/**
- *     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(ata_wait_after_reset);
 
 /**
  *     ata_std_prereset - prepare for reset
@@ -4026,118 +3529,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
 
        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;
-}
+EXPORT_SYMBOL_GPL(ata_std_prereset);
 
 /**
  *     sata_std_hardreset - COMRESET w/o waiting or classification
@@ -4164,6 +3556,7 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
        rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
        return online ? -EAGAIN : rc;
 }
+EXPORT_SYMBOL_GPL(sata_std_hardreset);
 
 /**
  *     ata_std_postreset - standard postreset callback
@@ -4192,6 +3585,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
 
        DPRINTK("EXIT\n");
 }
+EXPORT_SYMBOL_GPL(ata_std_postreset);
 
 /**
  *     ata_dev_same_device - Determine whether new ID matches configured device
@@ -4979,11 +4373,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc)
 
        return ATA_DEFER_LINK;
 }
+EXPORT_SYMBOL_GPL(ata_std_qc_defer);
 
 enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc)
 {
        return AC_ERR_OK;
 }
+EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
 
 /**
  *     ata_sg_init - Associate command with scatter-gather table.
@@ -5327,6 +4723,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                __ata_qc_complete(qc);
        }
 }
+EXPORT_SYMBOL_GPL(ata_qc_complete);
 
 /**
  *     ata_qc_get_active - get bitmask of active qcs
@@ -5352,64 +4749,6 @@ u64 ata_qc_get_active(struct ata_port *ap)
 }
 EXPORT_SYMBOL_GPL(ata_qc_get_active);
 
-/**
- *     ata_qc_complete_multiple - Complete multiple qcs successfully
- *     @ap: port in question
- *     @qc_active: new qc_active mask
- *
- *     Complete in-flight commands.  This functions is meant to be
- *     called from low-level driver's interrupt routine to complete
- *     requests normally.  ap->qc_active and @qc_active is compared
- *     and commands are completed accordingly.
- *
- *     Always use this function when completing multiple NCQ commands
- *     from IRQ handlers instead of calling ata_qc_complete()
- *     multiple times to keep IRQ expect status properly in sync.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- *
- *     RETURNS:
- *     Number of completed commands on success, -errno otherwise.
- */
-int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active)
-{
-       u64 done_mask, ap_qc_active = ap->qc_active;
-       int nr_done = 0;
-
-       /*
-        * If the internal tag is set on ap->qc_active, then we care about
-        * bit0 on the passed in qc_active mask. Move that bit up to match
-        * the internal tag.
-        */
-       if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) {
-               qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL;
-               qc_active ^= qc_active & 0x01;
-       }
-
-       done_mask = ap_qc_active ^ qc_active;
-
-       if (unlikely(done_mask & qc_active)) {
-               ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n",
-                            ap->qc_active, qc_active);
-               return -EINVAL;
-       }
-
-       while (done_mask) {
-               struct ata_queued_cmd *qc;
-               unsigned int tag = __ffs64(done_mask);
-
-               qc = ata_qc_from_tag(ap, tag);
-               if (qc) {
-                       ata_qc_complete(qc);
-                       nr_done++;
-               }
-               done_mask &= ~(1ULL << tag);
-       }
-
-       return nr_done;
-}
-
 /**
  *     ata_qc_issue - issue taskfile to device
  *     @qc: command to issue to device
@@ -5485,111 +4824,6 @@ err:
        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
  *     @link: ATA link to test
@@ -5663,6 +4897,7 @@ bool ata_link_online(struct ata_link *link)
        return ata_phys_link_online(link) ||
                (slave && ata_phys_link_online(slave));
 }
+EXPORT_SYMBOL_GPL(ata_link_online);
 
 /**
  *     ata_link_offline - test whether the given link is offline
@@ -5689,6 +4924,7 @@ bool ata_link_offline(struct ata_link *link)
        return ata_phys_link_offline(link) &&
                (!slave || ata_phys_link_offline(slave));
 }
+EXPORT_SYMBOL_GPL(ata_link_offline);
 
 #ifdef CONFIG_PM
 static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
@@ -5875,6 +5111,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
        host->dev->power.power_state = mesg;
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_host_suspend);
 
 /**
  *     ata_host_resume - resume host
@@ -5886,6 +5123,7 @@ void ata_host_resume(struct ata_host *host)
 {
        host->dev->power.power_state = PMSG_ON;
 }
+EXPORT_SYMBOL_GPL(ata_host_resume);
 #endif
 
 const struct device_type ata_port_type = {
@@ -6105,6 +5343,7 @@ void ata_host_put(struct ata_host *host)
 {
        kref_put(&host->kref, ata_host_release);
 }
+EXPORT_SYMBOL_GPL(ata_host_put);
 
 /**
  *     ata_host_alloc - allocate and init basic ATA host resources
@@ -6178,6 +5417,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
        kfree(host);
        return NULL;
 }
+EXPORT_SYMBOL_GPL(ata_host_alloc);
 
 /**
  *     ata_host_alloc_pinfo - alloc host and init with port_info array
@@ -6226,68 +5466,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
 
        return host;
 }
-
-/**
- *     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_host_alloc_pinfo);
 
 static void ata_host_stop(struct device *gendev, void *res)
 {
@@ -6436,6 +5615,7 @@ int ata_host_start(struct ata_host *host)
        devres_free(start_dr);
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_host_start);
 
 /**
  *     ata_sas_host_init - Initialize a host struct for sas (ipr, libsas)
@@ -6454,6 +5634,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
        host->ops = ops;
        kref_init(&host->kref);
 }
+EXPORT_SYMBOL_GPL(ata_host_init);
 
 void __ata_port_probe(struct ata_port *ap)
 {
@@ -6609,6 +5790,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        return rc;
 
 }
+EXPORT_SYMBOL_GPL(ata_host_register);
 
 /**
  *     ata_host_activate - start host, request IRQ and register it
@@ -6671,6 +5853,7 @@ int ata_host_activate(struct ata_host *host, int irq,
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_host_activate);
 
 /**
  *     ata_port_detach - Detach ATA port in preparation of device removal
@@ -6746,6 +5929,7 @@ void ata_host_detach(struct ata_host *host)
        /* the host is dead now, dissociate ACPI */
        ata_acpi_dissociate(host);
 }
+EXPORT_SYMBOL_GPL(ata_host_detach);
 
 #ifdef CONFIG_PCI
 
@@ -6766,6 +5950,7 @@ void ata_pci_remove_one(struct pci_dev *pdev)
 
        ata_host_detach(host);
 }
+EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 
 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);
        }
 }
+EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
 
 /* move to PCI subsystem */
 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;
 }
+EXPORT_SYMBOL_GPL(pci_test_config_bits);
 
 #ifdef CONFIG_PM
 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)
                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)
 {
@@ -6848,6 +6036,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev)
        pci_set_master(pdev);
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
 
 int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
@@ -6862,6 +6051,7 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
 
 int ata_pci_device_resume(struct pci_dev *pdev)
 {
@@ -6873,8 +6063,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
                ata_host_resume(host);
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_pci_device_resume);
 #endif /* CONFIG_PM */
-
 #endif /* CONFIG_PCI */
 
 /**
@@ -6896,7 +6086,9 @@ int ata_platform_remove_one(struct platform_device *pdev)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_platform_remove_one);
 
+#ifdef CONFIG_ATA_FORCE
 static int __init ata_parse_force_one(char **cur,
                                      struct ata_force_ent *force_ent,
                                      const char **reason)
@@ -7076,6 +6268,15 @@ static void __init ata_parse_force_param(void)
        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)
 {
        int rc;
@@ -7084,7 +6285,7 @@ static int __init ata_init(void)
 
        rc = ata_sff_init();
        if (rc) {
-               kfree(ata_force_tbl);
+               ata_free_force_param();
                return rc;
        }
 
@@ -7108,7 +6309,7 @@ static void __exit ata_exit(void)
        ata_release_transport(ata_scsi_transport_template);
        libata_transport_exit();
        ata_sff_exit();
-       kfree(ata_force_tbl);
+       ata_free_force_param();
 }
 
 subsys_initcall(ata_init);
@@ -7120,6 +6321,7 @@ int ata_ratelimit(void)
 {
        return __ratelimit(&ratelimit);
 }
+EXPORT_SYMBOL_GPL(ata_ratelimit);
 
 /**
  *     ata_msleep - ATA EH owner aware msleep
@@ -7152,6 +6354,7 @@ void ata_msleep(struct ata_port *ap, unsigned int msecs)
        if (owns_eh)
                ata_eh_acquire(ap);
 }
+EXPORT_SYMBOL_GPL(ata_msleep);
 
 /**
  *     ata_wait_register - wait until register value changes
@@ -7198,38 +6401,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
 
        return tmp;
 }
-
-/**
- *     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);
+EXPORT_SYMBOL_GPL(ata_wait_register);
 
 /*
  * Dummy port_ops
@@ -7251,10 +6423,12 @@ struct ata_port_operations ata_dummy_port_ops = {
        .sched_eh               = ata_std_sched_eh,
        .end_eh                 = ata_std_end_eh,
 };
+EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 
 const struct ata_port_info ata_dummy_port_info = {
        .port_ops               = &ata_dummy_port_ops,
 };
+EXPORT_SYMBOL_GPL(ata_dummy_port_info);
 
 /*
  * Utility print functions
@@ -7322,127 +6496,3 @@ void ata_print_version(const struct device *dev, const char *version)
        dev_printk(KERN_DEBUG, dev, "version %s\n", version);
 }
 EXPORT_SYMBOL(ata_print_version);
-
-/*
- * libata is essentially a library of internal helper functions for
- * low-level ATA host controller drivers.  As such, the API/ABI is
- * likely to change as new drivers are added and updated.
- * Do not depend on ABI/API stability.
- */
-EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
-EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
-EXPORT_SYMBOL_GPL(sata_deb_timing_long);
-EXPORT_SYMBOL_GPL(ata_base_port_ops);
-EXPORT_SYMBOL_GPL(sata_port_ops);
-EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
-EXPORT_SYMBOL_GPL(ata_dummy_port_info);
-EXPORT_SYMBOL_GPL(ata_link_next);
-EXPORT_SYMBOL_GPL(ata_dev_next);
-EXPORT_SYMBOL_GPL(ata_std_bios_param);
-EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
-EXPORT_SYMBOL_GPL(ata_host_init);
-EXPORT_SYMBOL_GPL(ata_host_alloc);
-EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
-EXPORT_SYMBOL_GPL(ata_slave_link_init);
-EXPORT_SYMBOL_GPL(ata_host_start);
-EXPORT_SYMBOL_GPL(ata_host_register);
-EXPORT_SYMBOL_GPL(ata_host_activate);
-EXPORT_SYMBOL_GPL(ata_host_detach);
-EXPORT_SYMBOL_GPL(ata_sg_init);
-EXPORT_SYMBOL_GPL(ata_qc_complete);
-EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
-EXPORT_SYMBOL_GPL(atapi_cmd_type);
-EXPORT_SYMBOL_GPL(ata_tf_to_fis);
-EXPORT_SYMBOL_GPL(ata_tf_from_fis);
-EXPORT_SYMBOL_GPL(ata_pack_xfermask);
-EXPORT_SYMBOL_GPL(ata_unpack_xfermask);
-EXPORT_SYMBOL_GPL(ata_xfer_mask2mode);
-EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
-EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
-EXPORT_SYMBOL_GPL(ata_mode_string);
-EXPORT_SYMBOL_GPL(ata_id_xfermask);
-EXPORT_SYMBOL_GPL(ata_do_set_mode);
-EXPORT_SYMBOL_GPL(ata_std_qc_defer);
-EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
-EXPORT_SYMBOL_GPL(ata_dev_disable);
-EXPORT_SYMBOL_GPL(sata_set_spd);
-EXPORT_SYMBOL_GPL(ata_wait_after_reset);
-EXPORT_SYMBOL_GPL(sata_link_debounce);
-EXPORT_SYMBOL_GPL(sata_link_resume);
-EXPORT_SYMBOL_GPL(sata_link_scr_lpm);
-EXPORT_SYMBOL_GPL(ata_std_prereset);
-EXPORT_SYMBOL_GPL(sata_link_hardreset);
-EXPORT_SYMBOL_GPL(sata_std_hardreset);
-EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_dev_classify);
-EXPORT_SYMBOL_GPL(ata_dev_pair);
-EXPORT_SYMBOL_GPL(ata_ratelimit);
-EXPORT_SYMBOL_GPL(ata_msleep);
-EXPORT_SYMBOL_GPL(ata_wait_register);
-EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
-EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
-EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
-EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
-EXPORT_SYMBOL_GPL(__ata_change_queue_depth);
-EXPORT_SYMBOL_GPL(sata_scr_valid);
-EXPORT_SYMBOL_GPL(sata_scr_read);
-EXPORT_SYMBOL_GPL(sata_scr_write);
-EXPORT_SYMBOL_GPL(sata_scr_write_flush);
-EXPORT_SYMBOL_GPL(ata_link_online);
-EXPORT_SYMBOL_GPL(ata_link_offline);
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_host_suspend);
-EXPORT_SYMBOL_GPL(ata_host_resume);
-#endif /* CONFIG_PM */
-EXPORT_SYMBOL_GPL(ata_id_string);
-EXPORT_SYMBOL_GPL(ata_id_c_string);
-EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
-EXPORT_SYMBOL_GPL(ata_scsi_simulate);
-
-EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
-EXPORT_SYMBOL_GPL(ata_timing_find_mode);
-EXPORT_SYMBOL_GPL(ata_timing_compute);
-EXPORT_SYMBOL_GPL(ata_timing_merge);
-EXPORT_SYMBOL_GPL(ata_timing_cycle2mode);
-
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_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);
index 3bfd9da584734db2b96d7ec93c60fdb79011e4b5..474c6c34fe022dc92f5d5f4e8c7e864bc69cc2f6 100644 (file)
@@ -2,10 +2,6 @@
 /*
  *  libata-eh.c - libata error handling
  *
- *  Maintained by:  Tejun Heo <tj@kernel.org>
- *                 Please ALWAYS copy linux-ide@vger.kernel.org
- *                 on emails.
- *
  *  Copyright 2006 Tejun Heo <htejun@gmail.com>
  *
  *  libata documentation is available via 'make {ps|pdf}docs',
@@ -184,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
        __ata_ehi_pushv_desc(ehi, fmt, args);
        va_end(args);
 }
+EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
 
 /**
  *     ata_ehi_push_desc - push error description with separator
@@ -207,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
        __ata_ehi_pushv_desc(ehi, fmt, args);
        va_end(args);
 }
+EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
 
 /**
  *     ata_ehi_clear_desc - clean error description
@@ -222,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
        ehi->desc[0] = '\0';
        ehi->desc_len = 0;
 }
+EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
 
 /**
  *     ata_port_desc - append port description
@@ -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);
        va_end(args);
 }
+EXPORT_SYMBOL_GPL(ata_port_desc);
 
 #ifdef CONFIG_PCI
-
 /**
  *     ata_port_pbar_desc - append PCI BAR description
  *     @ap: target ATA port
@@ -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,
                                start + (unsigned long long)offset);
 }
-
+EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
 #endif /* CONFIG_PCI */
 
 static int ata_lookup_timeout_table(u8 cmd)
@@ -973,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap)
        /* see: ata_std_sched_eh, unless you know better */
        ap->ops->sched_eh(ap);
 }
+EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
 
 static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
 {
@@ -1015,6 +1015,7 @@ int ata_link_abort(struct ata_link *link)
 {
        return ata_do_link_abort(link->ap, link);
 }
+EXPORT_SYMBOL_GPL(ata_link_abort);
 
 /**
  *     ata_port_abort - abort all qc's on the port
@@ -1032,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap)
 {
        return ata_do_link_abort(ap, NULL);
 }
+EXPORT_SYMBOL_GPL(ata_port_abort);
 
 /**
  *     __ata_port_freeze - freeze port
@@ -1088,79 +1090,7 @@ int ata_port_freeze(struct ata_port *ap)
 
        return nr_aborted;
 }
-
-/**
- *     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(ata_port_freeze);
 
 /**
  *     ata_eh_freeze_port - EH helper to freeze port
@@ -1182,6 +1112,7 @@ void ata_eh_freeze_port(struct ata_port *ap)
        __ata_port_freeze(ap);
        spin_unlock_irqrestore(ap->lock, flags);
 }
+EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
 
 /**
  *     ata_port_thaw_port - EH helper to thaw port
@@ -1289,6 +1220,7 @@ void ata_dev_disable(struct ata_device *dev)
         */
        ata_ering_clear(&dev->ering);
 }
+EXPORT_SYMBOL_GPL(ata_dev_disable);
 
 /**
  *     ata_eh_detach_dev - detach ATA device
@@ -1419,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask)
        return "unknown error";
 }
 
-/**
- *     ata_eh_read_log_10h - Read log page 10h for NCQ error details
- *     @dev: Device to read log page 10h from
- *     @tag: Resulting tag of the failed command
- *     @tf: Resulting taskfile registers of the failed command
- *
- *     Read log page 10h to obtain NCQ error details and clear error
- *     condition.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-static int ata_eh_read_log_10h(struct ata_device *dev,
-                              int *tag, struct ata_taskfile *tf)
-{
-       u8 *buf = dev->link->ap->sector_buf;
-       unsigned int err_mask;
-       u8 csum;
-       int i;
-
-       err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);
-       if (err_mask)
-               return -EIO;
-
-       csum = 0;
-       for (i = 0; i < ATA_SECT_SIZE; i++)
-               csum += buf[i];
-       if (csum)
-               ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n",
-                            csum);
-
-       if (buf[0] & 0x80)
-               return -ENOENT;
-
-       *tag = buf[0] & 0x1f;
-
-       tf->command = buf[2];
-       tf->feature = buf[3];
-       tf->lbal = buf[4];
-       tf->lbam = buf[5];
-       tf->lbah = buf[6];
-       tf->device = buf[7];
-       tf->hob_lbal = buf[8];
-       tf->hob_lbam = buf[9];
-       tf->hob_lbah = buf[10];
-       tf->nsect = buf[12];
-       tf->hob_nsect = buf[13];
-       if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
-               tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
-
-       return 0;
-}
-
 /**
  *     atapi_eh_tur - perform ATAPI TEST_UNIT_READY
  *     @dev: target ATAPI device
@@ -1658,80 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link)
        ehc->i.action |= action;
 }
 
-/**
- *     ata_eh_analyze_ncq_error - analyze NCQ error
- *     @link: ATA link to analyze NCQ error for
- *
- *     Read log page 10h, determine the offending qc and acquire
- *     error status TF.  For NCQ device errors, all LLDDs have to do
- *     is setting AC_ERR_DEV in ehi->err_mask.  This function takes
- *     care of the rest.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- */
-void ata_eh_analyze_ncq_error(struct ata_link *link)
-{
-       struct ata_port *ap = link->ap;
-       struct ata_eh_context *ehc = &link->eh_context;
-       struct ata_device *dev = link->device;
-       struct ata_queued_cmd *qc;
-       struct ata_taskfile tf;
-       int tag, rc;
-
-       /* if frozen, we can't do much */
-       if (ap->pflags & ATA_PFLAG_FROZEN)
-               return;
-
-       /* is it NCQ device error? */
-       if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV))
-               return;
-
-       /* has LLDD analyzed already? */
-       ata_qc_for_each_raw(ap, qc, tag) {
-               if (!(qc->flags & ATA_QCFLAG_FAILED))
-                       continue;
-
-               if (qc->err_mask)
-                       return;
-       }
-
-       /* okay, this error is ours */
-       memset(&tf, 0, sizeof(tf));
-       rc = ata_eh_read_log_10h(dev, &tag, &tf);
-       if (rc) {
-               ata_link_err(link, "failed to read log page 10h (errno=%d)\n",
-                            rc);
-               return;
-       }
-
-       if (!(link->sactive & (1 << tag))) {
-               ata_link_err(link, "log page 10h reported inactive tag %d\n",
-                            tag);
-               return;
-       }
-
-       /* we've got the perpetrator, condemn it */
-       qc = __ata_qc_from_tag(ap, tag);
-       memcpy(&qc->result_tf, &tf, sizeof(tf));
-       qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
-       qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
-       if (dev->class == ATA_DEV_ZAC &&
-           ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
-               char sense_key, asc, ascq;
-
-               sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
-               asc = (qc->result_tf.auxiliary >> 8) & 0xff;
-               ascq = qc->result_tf.auxiliary & 0xff;
-               ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
-               ata_scsi_set_sense_information(dev, qc->scsicmd,
-                                              &qc->result_tf);
-               qc->flags |= ATA_QCFLAG_SENSE_VALID;
-       }
-
-       ehc->i.err_mask &= ~AC_ERR_DEV;
-}
-
 /**
  *     ata_eh_analyze_tf - analyze taskfile of a failed qc
  *     @qc: qc to analyze
@@ -3436,7 +3238,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        int rc;
 
        /* 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;
 
        /*
@@ -4052,6 +3855,7 @@ void ata_std_error_handler(struct ata_port *ap)
 
        ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
 }
+EXPORT_SYMBOL_GPL(ata_std_error_handler);
 
 #ifdef CONFIG_PM
 /**
diff --git a/drivers/ata/libata-pata-timings.c b/drivers/ata/libata-pata-timings.c
new file mode 100644 (file)
index 0000000..af34122
--- /dev/null
@@ -0,0 +1,192 @@
+// 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);
diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
new file mode 100644 (file)
index 0000000..c16423e
--- /dev/null
@@ -0,0 +1,1483 @@
+// 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);
index eb2eb599e602303f1a4cdac487cda3f914cd9d59..36e588d88b9565a86b667f4fd03c72676255d98e 100644 (file)
@@ -2,10 +2,6 @@
 /*
  *  libata-scsi.c - helper library for ATA
  *
- *  Maintained by:  Tejun Heo <tj@kernel.org>
- *                 Please ALWAYS copy linux-ide@vger.kernel.org
- *                 on emails.
- *
  *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2004 Jeff Garzik
  *
 #include <linux/suspend.h>
 #include <asm/unaligned.h>
 #include <linux/ioprio.h>
+#include <linux/of.h>
 
 #include "libata.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 u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
@@ -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,
                                        const struct scsi_device *scsidev);
-static struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
-                                           const struct scsi_device *scsidev);
 
 #define RW_RECOVERY_MPAGE 0x1
 #define RW_RECOVERY_MPAGE_LEN 12
@@ -90,71 +85,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
        0, 30   /* extended self test time, see 05-359r1 */
 };
 
-static const char *ata_lpm_policy_names[] = {
-       [ATA_LPM_UNKNOWN]               = "max_performance",
-       [ATA_LPM_MAX_POWER]             = "max_performance",
-       [ATA_LPM_MED_POWER]             = "medium_power",
-       [ATA_LPM_MED_POWER_WITH_DIPM]   = "med_power_with_dipm",
-       [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial",
-       [ATA_LPM_MIN_POWER]             = "min_power",
-};
-
-static ssize_t ata_scsi_lpm_store(struct device *device,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(device);
-       struct ata_port *ap = ata_shost_to_port(shost);
-       struct ata_link *link;
-       struct ata_device *dev;
-       enum ata_lpm_policy policy;
-       unsigned long flags;
-
-       /* UNKNOWN is internal state, iterate from MAX_POWER */
-       for (policy = ATA_LPM_MAX_POWER;
-            policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) {
-               const char *name = ata_lpm_policy_names[policy];
-
-               if (strncmp(name, buf, strlen(name)) == 0)
-                       break;
-       }
-       if (policy == ARRAY_SIZE(ata_lpm_policy_names))
-               return -EINVAL;
-
-       spin_lock_irqsave(ap->lock, flags);
-
-       ata_for_each_link(link, ap, EDGE) {
-               ata_for_each_dev(dev, &ap->link, ENABLED) {
-                       if (dev->horkage & ATA_HORKAGE_NOLPM) {
-                               count = -EOPNOTSUPP;
-                               goto out_unlock;
-                       }
-               }
-       }
-
-       ap->target_lpm_policy = policy;
-       ata_port_schedule_eh(ap);
-out_unlock:
-       spin_unlock_irqrestore(ap->lock, flags);
-       return count;
-}
-
-static ssize_t ata_scsi_lpm_show(struct device *dev,
-                                struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ata_port *ap = ata_shost_to_port(shost);
-
-       if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names))
-               return -EINVAL;
-
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ata_lpm_policy_names[ap->target_lpm_policy]);
-}
-DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
-           ata_scsi_lpm_show, ata_scsi_lpm_store);
-EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
-
 static ssize_t ata_scsi_park_show(struct device *device,
                                  struct device_attribute *attr, char *buf)
 {
@@ -258,83 +188,6 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
            ata_scsi_park_show, ata_scsi_park_store);
 EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
 
-static ssize_t ata_ncq_prio_enable_show(struct device *device,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct scsi_device *sdev = to_scsi_device(device);
-       struct ata_port *ap;
-       struct ata_device *dev;
-       bool ncq_prio_enable;
-       int rc = 0;
-
-       ap = ata_shost_to_port(sdev->host);
-
-       spin_lock_irq(ap->lock);
-       dev = ata_scsi_find_dev(ap, sdev);
-       if (!dev) {
-               rc = -ENODEV;
-               goto unlock;
-       }
-
-       ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
-
-unlock:
-       spin_unlock_irq(ap->lock);
-
-       return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable);
-}
-
-static ssize_t ata_ncq_prio_enable_store(struct device *device,
-                                        struct device_attribute *attr,
-                                        const char *buf, size_t len)
-{
-       struct scsi_device *sdev = to_scsi_device(device);
-       struct ata_port *ap;
-       struct ata_device *dev;
-       long int input;
-       int rc;
-
-       rc = kstrtol(buf, 10, &input);
-       if (rc)
-               return rc;
-       if ((input < 0) || (input > 1))
-               return -EINVAL;
-
-       ap = ata_shost_to_port(sdev->host);
-       dev = ata_scsi_find_dev(ap, sdev);
-       if (unlikely(!dev))
-               return  -ENODEV;
-
-       spin_lock_irq(ap->lock);
-       if (input)
-               dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
-       else
-               dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
-
-       dev->link->eh_info.action |= ATA_EH_REVALIDATE;
-       dev->link->eh_info.flags |= ATA_EHI_QUIET;
-       ata_port_schedule_eh(ap);
-       spin_unlock_irq(ap->lock);
-
-       ata_port_wait_eh(ap);
-
-       if (input) {
-               spin_lock_irq(ap->lock);
-               if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
-                       dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
-                       rc = -EIO;
-               }
-               spin_unlock_irq(ap->lock);
-       }
-
-       return rc ? rc : len;
-}
-
-DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
-           ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
-EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
-
 void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
                        u8 sk, u8 asc, u8 ascq)
 {
@@ -383,90 +236,8 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev,
                                     field, 0xff, 0);
 }
 
-static ssize_t
-ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ata_port *ap = ata_shost_to_port(shost);
-       if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM))
-               return ap->ops->em_store(ap, buf, count);
-       return -EINVAL;
-}
-
-static ssize_t
-ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr,
-                        char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ata_port *ap = ata_shost_to_port(shost);
-
-       if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM))
-               return ap->ops->em_show(ap, buf);
-       return -EINVAL;
-}
-DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR,
-               ata_scsi_em_message_show, ata_scsi_em_message_store);
-EXPORT_SYMBOL_GPL(dev_attr_em_message);
-
-static ssize_t
-ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr,
-                             char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ata_port *ap = ata_shost_to_port(shost);
-
-       return snprintf(buf, 23, "%d\n", ap->em_message_type);
-}
-DEVICE_ATTR(em_message_type, S_IRUGO,
-                 ata_scsi_em_message_type_show, NULL);
-EXPORT_SYMBOL_GPL(dev_attr_em_message_type);
-
-static ssize_t
-ata_scsi_activity_show(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct ata_port *ap = ata_shost_to_port(sdev->host);
-       struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
-
-       if (atadev && ap->ops->sw_activity_show &&
-           (ap->flags & ATA_FLAG_SW_ACTIVITY))
-               return ap->ops->sw_activity_show(atadev, buf);
-       return -EINVAL;
-}
-
-static ssize_t
-ata_scsi_activity_store(struct device *dev, struct device_attribute *attr,
-       const char *buf, size_t count)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       struct ata_port *ap = ata_shost_to_port(sdev->host);
-       struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
-       enum sw_activity val;
-       int rc;
-
-       if (atadev && ap->ops->sw_activity_store &&
-           (ap->flags & ATA_FLAG_SW_ACTIVITY)) {
-               val = simple_strtoul(buf, NULL, 0);
-               switch (val) {
-               case OFF: case BLINK_ON: case BLINK_OFF:
-                       rc = ap->ops->sw_activity_store(atadev, val);
-                       if (!rc)
-                               return count;
-                       else
-                               return rc;
-               }
-       }
-       return -EINVAL;
-}
-DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show,
-                       ata_scsi_activity_store);
-EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
-
 struct device_attribute *ata_common_sdev_attrs[] = {
        &dev_attr_unload_heads,
-       &dev_attr_ncq_prio_enable,
        NULL
 };
 EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
@@ -499,6 +270,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ata_std_bios_param);
 
 /**
  *     ata_scsi_unlock_native_capacity - unlock native capacity
@@ -528,6 +300,7 @@ void ata_scsi_unlock_native_capacity(struct scsi_device *sdev)
        spin_unlock_irqrestore(ap->lock, flags);
        ata_port_wait_eh(ap);
 }
+EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
 
 /**
  *     ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
@@ -1215,7 +988,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
        scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block);
 }
 
-static void ata_scsi_sdev_config(struct scsi_device *sdev)
+void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
@@ -1255,8 +1028,7 @@ static int atapi_drain_needed(struct request *rq)
        return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC;
 }
 
-static int ata_scsi_dev_config(struct scsi_device *sdev,
-                              struct ata_device *dev)
+int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
 {
        struct request_queue *q = sdev->request_queue;
 
@@ -1344,6 +1116,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 
 /**
  *     ata_scsi_slave_destroy - SCSI device is about to be destroyed
@@ -1383,71 +1156,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
        q->dma_drain_buffer = NULL;
        q->dma_drain_size = 0;
 }
-
-/**
- *     __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);
-}
+EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
 
 /**
  *     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)
  */
 static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
 {
-       struct ata_taskfile tf;
-
-       memset(&tf, 0, sizeof(tf));
-
        rbuf[1] = 0x89;                 /* our page code */
        rbuf[2] = (0x238 >> 8);         /* page size fixed at 238h */
        rbuf[3] = (0x238 & 0xff);
@@ -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[32], DRV_VERSION, 4);
 
-       /* we don't store the ATA device signature, so we fake it */
-
-       tf.command = ATA_DRDY;          /* really, this is Status reg */
-       tf.lbal = 0x1;
-       tf.nsect = 0x1;
-
-       ata_tf_to_fis(&tf, 0, 1, &rbuf[36]);    /* TODO: PMP? */
        rbuf[36] = 0x34;                /* force D2H Reg FIS (34h) */
+       rbuf[37] = (1 << 7);            /* bit 7 indicates Command FIS */
+                                       /* TODO: PMP? */
+
+       /* we don't store the ATA device signature, so we fake it */
+       rbuf[38] = ATA_DRDY;            /* really, this is Status reg */
+       rbuf[40] = 0x1;
+       rbuf[48] = 0x1;
 
        rbuf[56] = ATA_CMD_ID_ATA;
 
@@ -3089,7 +2794,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
  *     RETURNS:
  *     Associated ATA device, or %NULL if not found.
  */
-static struct ata_device *
+struct ata_device *
 ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
 {
        struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
@@ -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().
  */
 
-static inline void ata_scsi_dump_cdb(struct ata_port *ap,
-                                    struct scsi_cmnd *cmd)
+void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd)
 {
 #ifdef ATA_VERBOSE_DEBUG
        struct scsi_device *scsidev = cmd->device;
@@ -4312,8 +4016,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
 #endif
 }
 
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
-                                     struct ata_device *dev)
+int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
 {
        u8 scsi_op = scmd->cmnd[0];
        ata_xlat_func_t xlat_func;
@@ -4407,6 +4110,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 
 /**
  *     ata_scsi_simulate - simulate SCSI command on ATA device
@@ -4562,26 +4266,51 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                 */
                shost->max_host_blocked = 1;
 
-               rc = scsi_add_host_with_dma(ap->scsi_host,
-                                               &ap->tdev, ap->host->dev);
+               rc = scsi_add_host_with_dma(shost, &ap->tdev, ap->host->dev);
                if (rc)
-                       goto err_add;
+                       goto err_alloc;
        }
 
        return 0;
 
- err_add:
-       scsi_host_put(host->ports[i]->scsi_host);
  err_alloc:
        while (--i >= 0) {
                struct Scsi_Host *shost = host->ports[i]->scsi_host;
 
+               /* scsi_host_put() is in ata_devres_release() */
                scsi_remove_host(shost);
-               scsi_host_put(shost);
        }
        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)
 {
        int tries = 5;
@@ -4607,6 +4336,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
                                                 NULL);
                        if (!IS_ERR(sdev)) {
                                dev->sdev = sdev;
+                               ata_scsi_assign_ofnode(dev, ap);
                                scsi_device_put(sdev);
                        } else {
                                dev->sdev = NULL;
@@ -4929,214 +4659,3 @@ void ata_scsi_dev_rescan(struct work_struct *work)
        spin_unlock_irqrestore(ap->lock, flags);
        mutex_unlock(&ap->scsi_scan_mutex);
 }
-
-/**
- *     ata_sas_port_alloc - Allocate port for a SAS attached SATA device
- *     @host: ATA host container for all SAS ports
- *     @port_info: Information from low-level host driver
- *     @shost: SCSI host that the scsi device is attached to
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
- *
- *     RETURNS:
- *     ata_port pointer on success / NULL on failure.
- */
-
-struct ata_port *ata_sas_port_alloc(struct ata_host *host,
-                                   struct ata_port_info *port_info,
-                                   struct Scsi_Host *shost)
-{
-       struct ata_port *ap;
-
-       ap = ata_port_alloc(host);
-       if (!ap)
-               return NULL;
-
-       ap->port_no = 0;
-       ap->lock = &host->lock;
-       ap->pio_mask = port_info->pio_mask;
-       ap->mwdma_mask = port_info->mwdma_mask;
-       ap->udma_mask = port_info->udma_mask;
-       ap->flags |= port_info->flags;
-       ap->ops = port_info->port_ops;
-       ap->cbl = ATA_CBL_SATA;
-
-       return ap;
-}
-EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
-
-/**
- *     ata_sas_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Called just after data structures for each port are
- *     initialized.
- *
- *     May be used as the port_start() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-int ata_sas_port_start(struct ata_port *ap)
-{
-       /*
-        * the port is marked as frozen at allocation time, but if we don't
-        * have new eh, we won't thaw it
-        */
-       if (!ap->ops->error_handler)
-               ap->pflags &= ~ATA_PFLAG_FROZEN;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ata_sas_port_start);
-
-/**
- *     ata_port_stop - Undo ata_sas_port_start()
- *     @ap: Port to shut down
- *
- *     May be used as the port_stop() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-void ata_sas_port_stop(struct ata_port *ap)
-{
-}
-EXPORT_SYMBOL_GPL(ata_sas_port_stop);
-
-/**
- * ata_sas_async_probe - simply schedule probing and return
- * @ap: Port to probe
- *
- * For batch scheduling of probe for sas attached ata devices, assumes
- * the port has already been through ata_sas_port_init()
- */
-void ata_sas_async_probe(struct ata_port *ap)
-{
-       __ata_port_probe(ap);
-}
-EXPORT_SYMBOL_GPL(ata_sas_async_probe);
-
-int ata_sas_sync_probe(struct ata_port *ap)
-{
-       return ata_port_probe(ap);
-}
-EXPORT_SYMBOL_GPL(ata_sas_sync_probe);
-
-
-/**
- *     ata_sas_port_init - Initialize a SATA device
- *     @ap: SATA port to initialize
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
- *
- *     RETURNS:
- *     Zero on success, non-zero on error.
- */
-
-int ata_sas_port_init(struct ata_port *ap)
-{
-       int rc = ap->ops->port_start(ap);
-
-       if (rc)
-               return rc;
-       ap->print_id = atomic_inc_return(&ata_print_id);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ata_sas_port_init);
-
-int ata_sas_tport_add(struct device *parent, struct ata_port *ap)
-{
-       return ata_tport_add(parent, ap);
-}
-EXPORT_SYMBOL_GPL(ata_sas_tport_add);
-
-void ata_sas_tport_delete(struct ata_port *ap)
-{
-       ata_tport_delete(ap);
-}
-EXPORT_SYMBOL_GPL(ata_sas_tport_delete);
-
-/**
- *     ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc
- *     @ap: SATA port to destroy
- *
- */
-
-void ata_sas_port_destroy(struct ata_port *ap)
-{
-       if (ap->ops->port_stop)
-               ap->ops->port_stop(ap);
-       kfree(ap);
-}
-EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
-
-/**
- *     ata_sas_slave_configure - Default slave_config routine for libata devices
- *     @sdev: SCSI device to configure
- *     @ap: ATA port to which SCSI device is attached
- *
- *     RETURNS:
- *     Zero.
- */
-
-int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap)
-{
-       ata_scsi_sdev_config(sdev);
-       ata_scsi_dev_config(sdev, ap->link.device);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
-
-/**
- *     ata_sas_queuecmd - Issue SCSI cdb to libata-managed device
- *     @cmd: SCSI command to be sent
- *     @ap:    ATA port to which the command is being sent
- *
- *     RETURNS:
- *     Return value from __ata_scsi_queuecmd() if @cmd can be queued,
- *     0 otherwise.
- */
-
-int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap)
-{
-       int rc = 0;
-
-       ata_scsi_dump_cdb(ap, cmd);
-
-       if (likely(ata_dev_enabled(ap->link.device)))
-               rc = __ata_scsi_queuecmd(cmd, ap->link.device);
-       else {
-               cmd->result = (DID_BAD_TARGET << 16);
-               cmd->scsi_done(cmd);
-       }
-       return rc;
-}
-EXPORT_SYMBOL_GPL(ata_sas_queuecmd);
-
-int ata_sas_allocate_tag(struct ata_port *ap)
-{
-       unsigned int max_queue = ap->host->n_tags;
-       unsigned int i, tag;
-
-       for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) {
-               tag = tag < max_queue ? tag : 0;
-
-               /* the last tag is reserved for internal command. */
-               if (ata_tag_internal(tag))
-                       continue;
-
-               if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) {
-                       ap->sas_last_tag = tag;
-                       return tag;
-               }
-       }
-       return -1;
-}
-
-void ata_sas_free_tag(unsigned int tag, struct ata_port *ap)
-{
-       clear_bit(tag, &ap->sas_tag_allocated);
-}
index 038db94216a9173c76a1cf614dc013cc8ff6a4ea..ae7189d1a5682c305919ce7fc38ad977dc79fdee 100644 (file)
@@ -2,10 +2,6 @@
 /*
  *  libata-sff.c - helper library for PCI IDE BMDMA
  *
- *  Maintained by:  Tejun Heo <tj@kernel.org>
- *                 Please ALWAYS copy linux-ide@vger.kernel.org
- *                 on emails.
- *
  *  Copyright 2003-2006 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2006 Jeff Garzik
  *
index 12a505bb9c5b17db13cd854c0aa5613d1cfb4ae9..6a40e3c6cf492cd82f85b6b8bfc8ac0c14fc2cd9 100644 (file)
@@ -208,7 +208,7 @@ show_ata_port_##name(struct device *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)         \
@@ -479,7 +479,7 @@ show_ata_dev_##field(struct device *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)        \
@@ -533,7 +533,7 @@ show_ata_dev_id(struct device *dev,
        if (ata_dev->class == ATA_DEV_PMP)
                return 0;
        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],
                                    ((i+1) & 7) ? ' ' : '\n');
        }
@@ -552,7 +552,7 @@ show_ata_dev_gscr(struct device *dev,
        if (ata_dev->class != ATA_DEV_PMP)
                return 0;
        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],
                                    ((i+1) & 3) ? ' ' : '\n');
        }
@@ -581,7 +581,7 @@ show_ata_dev_trim(struct device *dev,
        else
                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);
index cd8090ad43e5a10124f2b0d0a3bac2b43166da8d..68cdd81d747c5cf7fadfbf868249a9e1bbe50309 100644 (file)
@@ -37,7 +37,11 @@ extern int libata_noacpi;
 extern int libata_allow_tpm;
 extern const struct device_type ata_port_type;
 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);
+#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_lba48(const struct ata_taskfile *tf);
 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,
 
 #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 */
 #ifdef CONFIG_ATA_ACPI
 extern unsigned int ata_acpi_gtf_filter;
@@ -112,6 +128,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
 #endif
 
 /* libata-scsi.c */
+extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
+                                           const struct scsi_device *scsidev);
 extern int ata_scsi_add_hosts(struct ata_host *host,
                              struct scsi_host_template *sht);
 extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
@@ -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_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
                              unsigned int id, u64 lun);
-int ata_sas_allocate_tag(struct ata_port *ap);
-void ata_sas_free_tag(unsigned int tag, struct ata_port *ap);
-
+void ata_scsi_sdev_config(struct scsi_device *sdev);
+int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev);
+void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd);
+int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev);
 
 /* libata-eh.c */
 extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
index c451d7d1c817aafb37fd6d791906d1363d56882b..8729f78cef5fdb1243508b0de7b286abd9420968 100644 (file)
@@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
 static void pdc_error_handler(struct ata_port *ap);
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
 static int pdc_pata_cable_detect(struct ata_port *ap);
-static int pdc_sata_cable_detect(struct ata_port *ap);
 
 static struct scsi_host_template pdc_ata_sht = {
        ATA_BASE_SHT(DRV_NAME),
@@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = {
 
 static struct ata_port_operations pdc_sata_ops = {
        .inherits               = &pdc_common_ops,
-       .cable_detect           = pdc_sata_cable_detect,
+       .cable_detect           = ata_cable_sata,
        .freeze                 = pdc_sata_freeze,
        .thaw                   = pdc_sata_thaw,
        .scr_read               = pdc_sata_scr_read,
@@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap)
        return ATA_CBL_PATA80;
 }
 
-static int pdc_sata_cable_detect(struct ata_port *ap)
-{
-       return ATA_CBL_SATA;
-}
-
 static int pdc_sata_scr_read(struct ata_link *link,
                             unsigned int sc_reg, u32 *val)
 {
index a7881f8eb05ee4ffb9571da0d2a9d21b62abb92a..1b6eaf8da5fa4aa306c53efa0797687190583ae5 100644 (file)
@@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO
 config SCSI_IPR
        tristate "IBM Power Linux RAID adapter support"
        depends on PCI && SCSI && ATA
+       select SATA_HOST
        select FW_LOADER
        select IRQ_POLL
        select SGL_ALLOC
index 5c6a5eff2f8ee95283530347a3317f3f78710833..052ee3a26f6eb2ddc508c0ddc141a85133a45d4a 100644 (file)
@@ -19,6 +19,7 @@ config SCSI_SAS_ATA
        bool "ATA support for libsas (requires libata)"
        depends on SCSI_SAS_LIBSAS
        depends on ATA = y || ATA = SCSI_SAS_LIBSAS
+       select SATA_HOST
        help
                Builds in ATA support into libsas.  Will necessitate
                the loading of libata along with libsas.
index 2ca9b7056a8291e8d69badd81c846e529230fc6a..cffa4714bfa84b2fb88e99ce6a9625e71602aa88 100644 (file)
@@ -57,8 +57,6 @@
 #define VPRINTK(fmt, args...)
 #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)                   \
 ({                                                             \
        static bool __print_once;                               \
@@ -176,6 +174,7 @@ enum {
        ATA_DEV_NONE            = 11,   /* no device */
 
        /* struct ata_link flags */
+       /* NOTE: struct ata_force_param currently stores lflags in u16 */
        ATA_LFLAG_NO_HRST       = (1 << 1), /* avoid hardreset */
        ATA_LFLAG_NO_SRST       = (1 << 2), /* avoid softreset */
        ATA_LFLAG_ASSUME_ATA    = (1 << 3), /* assume ATA class */
@@ -531,12 +530,14 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
                              unsigned long deadline);
 typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
 
-extern struct device_attribute dev_attr_link_power_management_policy;
 extern struct device_attribute dev_attr_unload_heads;
+#ifdef CONFIG_SATA_HOST
+extern struct device_attribute dev_attr_link_power_management_policy;
 extern struct device_attribute dev_attr_ncq_prio_enable;
 extern struct device_attribute dev_attr_em_message_type;
 extern struct device_attribute dev_attr_em_message;
 extern struct device_attribute dev_attr_sw_activity;
+#endif
 
 enum sw_activity {
        OFF,
@@ -1020,10 +1021,6 @@ struct ata_timing {
 /*
  * Core layer - drivers/ata/libata-core.c
  */
-extern const unsigned long sata_deb_timing_normal[];
-extern const unsigned long sata_deb_timing_hotplug[];
-extern const unsigned long sata_deb_timing_long[];
-
 extern struct ata_port_operations ata_dummy_port_ops;
 extern const struct ata_port_info ata_dummy_port_info;
 
@@ -1061,33 +1058,14 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf)
               (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT);
 }
 
-static inline const unsigned long *
-sata_ehc_deb_timing(struct ata_eh_context *ehc)
-{
-       if (ehc->i.flags & ATA_EHI_HOTPLUGGED)
-               return sata_deb_timing_hotplug;
-       else
-               return sata_deb_timing_normal;
-}
-
 static inline int ata_port_is_dummy(struct ata_port *ap)
 {
        return ap->ops == &ata_dummy_port_ops;
 }
 
-extern int sata_set_spd(struct ata_link *link);
 extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
 extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
                                int (*check_ready)(struct ata_link *link));
-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,
                              unsigned long deadline);
 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_pinfo(struct device *dev,
                        const struct ata_port_info * const * ppi, int n_ports);
-extern int ata_slave_link_init(struct ata_port *ap);
 extern void ata_host_get(struct ata_host *host);
 extern void ata_host_put(struct ata_host *host);
 extern int ata_host_start(struct ata_host *host);
@@ -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_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
                            unsigned int cmd, void __user *arg);
-extern void ata_sas_port_destroy(struct ata_port *);
-extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
-                                          struct ata_port_info *, struct Scsi_Host *);
-extern void ata_sas_async_probe(struct ata_port *ap);
-extern int ata_sas_sync_probe(struct ata_port *ap);
-extern int ata_sas_port_init(struct ata_port *);
-extern int ata_sas_port_start(struct ata_port *ap);
-extern int ata_sas_tport_add(struct device *parent, struct ata_port *ap);
-extern void ata_sas_tport_delete(struct ata_port *ap);
-extern void ata_sas_port_stop(struct ata_port *ap);
-extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
-extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap);
-extern int sata_scr_valid(struct ata_link *link);
-extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
-extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
-extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
 extern bool ata_link_online(struct ata_link *link);
 extern bool ata_link_offline(struct ata_link *link);
 #ifdef CONFIG_PM
@@ -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,
                        u32 val, unsigned long interval, unsigned long timeout);
 extern int atapi_cmd_type(u8 opcode);
-extern void ata_tf_to_fis(const struct ata_taskfile *tf,
-                         u8 pmp, int is_cmd, u8 *fis);
-extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
 extern unsigned long ata_pack_xfermask(unsigned long pio_mask,
                        unsigned long mwdma_mask, unsigned long udma_mask);
 extern void ata_unpack_xfermask(unsigned long xfer_mask,
@@ -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,
                                        struct ata_taskfile *tf, u16 *id);
 extern void ata_qc_complete(struct ata_queued_cmd *qc);
-extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active);
 extern u64 ata_qc_get_active(struct ata_port *ap);
 extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd);
 extern int ata_std_bios_param(struct scsi_device *sdev,
@@ -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 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);
+
+/*
+ * 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 int sata_async_notification(struct ata_port *ap);
 
 extern int ata_cable_40wire(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);
 
 /* Timing helpers */
 extern unsigned int ata_pio_need_iordy(const struct ata_device *);
-extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode);
-extern int ata_timing_compute(struct ata_device *, unsigned short,
-                             struct ata_timing *, int, int);
-extern void ata_timing_merge(const struct ata_timing *,
-                            const struct ata_timing *, struct ata_timing *,
-                            unsigned int);
 extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle);
 
 /* PCI */
@@ -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_port_abort(struct ata_port *ap);
 extern int ata_port_freeze(struct ata_port *ap);
-extern int sata_async_notification(struct ata_port *ap);
 
 extern void ata_eh_freeze_port(struct ata_port *ap);
 extern void ata_eh_thaw_port(struct ata_port *ap);
 
 extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
-extern void ata_eh_analyze_ncq_error(struct ata_link *link);
 
 extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
                      ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
@@ -1343,7 +1381,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
  * edge driver's module reference, otherwise the driver can be unloaded
  * even if the scsi_device is being accessed.
  */
-#define ATA_BASE_SHT(drv_name)                                 \
+#define __ATA_BASE_SHT(drv_name)                               \
        .module                 = THIS_MODULE,                  \
        .name                   = drv_name,                     \
        .ioctl                  = ata_scsi_ioctl,               \
@@ -1357,12 +1395,20 @@ extern struct device_attribute *ata_common_sdev_attrs[];
        .slave_configure        = ata_scsi_slave_config,        \
        .slave_destroy          = ata_scsi_slave_destroy,       \
        .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
 
+#ifdef CONFIG_SATA_HOST
+extern struct device_attribute *ata_ncq_sdev_attrs[];
+
 #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
+#endif
 
 /*
  * PMP helpers
@@ -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)
 {
+       if (!IS_ENABLED(CONFIG_SATA_HOST))
+               return 0;
        return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
                              ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ;
 }
@@ -1803,6 +1851,16 @@ static inline int ata_dma_enabled(struct ata_device *adev)
        return (adev->dma_mode == 0xFF ? 0 : 1);
 }
 
+/**************************************************************************
+ * PATA timings - drivers/ata/libata-pata-timings.c
+ */
+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
  */
index 352c0d708720a02134ac79b41eb0e6037c9491f6..977e66875a967a02737f5a3713508b775b35afac 100644 (file)
 
 /* Vendors and devices.  Sort key: vendor first, device next. */
 
+#define PCI_VENDOR_ID_LOONGSON         0x0014
+
 #define PCI_VENDOR_ID_TTTECH           0x0357
 #define PCI_DEVICE_ID_TTTECH_MC322     0x000a