From a900cc5cd846edc6964736834e098e88d7ecfcd6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Mar 2020 08:11:00 +0100 Subject: [PATCH 01/36] libata: transport: Use scnprintf() for avoiding potential buffer overflow Since snprintf() returns the would-be-output size instead of the actual output size, the succeeding calls may go beyond the given buffer limit. Fix it by replacing with scnprintf(). Signed-off-by: Takashi Iwai Signed-off-by: Jens Axboe --- drivers/ata/libata-transport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 12a505bb9c5b..6a40e3c6cf49 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -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;iid[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;igscr[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); From 9acb9fe18d863aacc99948963f8d5d447dc311be Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Tue, 10 Mar 2020 20:50:07 +0800 Subject: [PATCH 02/36] PCI: Add Loongson vendor ID Add the Loongson vendor ID to pci_ids.h to be used by the controller driver in the future. The Loongson vendor ID can be found at the following link: https://git.kernel.org/pub/scm/utils/pciutils/pciutils.git/tree/pci.ids Signed-off-by: Tiezhu Yang Signed-off-by: Jens Axboe --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 352c0d708720..977e66875a96 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -148,6 +148,8 @@ /* 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 From e49bd683e00bcc636bf2df79d4c8a0bda0314dc0 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Tue, 10 Mar 2020 20:50:08 +0800 Subject: [PATCH 03/36] AHCI: Add support for Loongson 7A1000 SATA controller Loongson 7A1000 SATA controller uses BAR0 as the base address register. Signed-off-by: Tiezhu Yang Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 11ea1aff40db..33d051a22ea6 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -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, @@ -589,6 +590,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 +1684,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 */ From 58def851063d2178c10622e436897e6285850077 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 3 Mar 2020 10:37:34 +0100 Subject: [PATCH 04/36] libata: drop BPRINTK() No users, drop it. Signed-off-by: Hannes Reinecke Reviewed-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/libata.h b/include/linux/libata.h index 2ca9b7056a82..710e09dae910 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -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; \ From 32d2545462c6cede998267b86e57cda5d1dc2225 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 27 Feb 2020 20:28:22 +0800 Subject: [PATCH 05/36] ahci: Add Intel Comet Lake H RAID PCI ID Add the PCI ID to the driver list to support this new device. Cc: stable@vger.kernel.org Signed-off-by: Kai-Heng Feng Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 33d051a22ea6..2025b29f17fa 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -402,6 +402,7 @@ 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, 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 */ From 1d72f7aec3595249dbb83291ccac041a2d676c57 Mon Sep 17 00:00:00 2001 From: John Garry Date: Fri, 28 Feb 2020 19:33:35 +0800 Subject: [PATCH 06/36] libata: Remove extra scsi_host_put() in ata_scsi_add_hosts() If the call to scsi_add_host_with_dma() in ata_scsi_add_hosts() fails, then we may get use-after-free KASAN warns: ================================================================== BUG: KASAN: use-after-free in kobject_put+0x24/0x180 Read of size 1 at addr ffff0026b8c80364 by task swapper/0/1 CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W 5.6.0-rc3-00004-g5a71b206ea82-dirty #1765 Hardware name: Huawei TaiShan 200 (Model 2280)/BC82AMDD, BIOS 2280-V2 CS V3.B160.01 02/24/2020 Call trace: dump_backtrace+0x0/0x298 show_stack+0x14/0x20 dump_stack+0x118/0x190 print_address_description.isra.9+0x6c/0x3b8 __kasan_report+0x134/0x23c kasan_report+0xc/0x18 __asan_load1+0x5c/0x68 kobject_put+0x24/0x180 put_device+0x10/0x20 scsi_host_put+0x10/0x18 ata_devres_release+0x74/0xb0 release_nodes+0x2d0/0x470 devres_release_all+0x50/0x78 really_probe+0x2d4/0x560 driver_probe_device+0x7c/0x148 device_driver_attach+0x94/0xa0 __driver_attach+0xa8/0x110 bus_for_each_dev+0xe8/0x158 driver_attach+0x30/0x40 bus_add_driver+0x220/0x2e0 driver_register+0xbc/0x1d0 __pci_register_driver+0xbc/0xd0 ahci_pci_driver_init+0x20/0x28 do_one_initcall+0xf0/0x608 kernel_init_freeable+0x31c/0x384 kernel_init+0x10/0x118 ret_from_fork+0x10/0x18 Allocated by task 5: save_stack+0x28/0xc8 __kasan_kmalloc.isra.8+0xbc/0xd8 kasan_kmalloc+0xc/0x18 __kmalloc+0x1a8/0x280 scsi_host_alloc+0x44/0x678 ata_scsi_add_hosts+0x74/0x268 ata_host_register+0x228/0x488 ahci_host_activate+0x1c4/0x2a8 ahci_init_one+0xd18/0x1298 local_pci_probe+0x74/0xf0 work_for_cpu_fn+0x2c/0x48 process_one_work+0x488/0xc08 worker_thread+0x330/0x5d0 kthread+0x1c8/0x1d0 ret_from_fork+0x10/0x18 Freed by task 5: save_stack+0x28/0xc8 __kasan_slab_free+0x118/0x180 kasan_slab_free+0x10/0x18 slab_free_freelist_hook+0xa4/0x1a0 kfree+0xd4/0x3a0 scsi_host_dev_release+0x100/0x148 device_release+0x7c/0xe0 kobject_put+0xb0/0x180 put_device+0x10/0x20 scsi_host_put+0x10/0x18 ata_scsi_add_hosts+0x210/0x268 ata_host_register+0x228/0x488 ahci_host_activate+0x1c4/0x2a8 ahci_init_one+0xd18/0x1298 local_pci_probe+0x74/0xf0 work_for_cpu_fn+0x2c/0x48 process_one_work+0x488/0xc08 worker_thread+0x330/0x5d0 kthread+0x1c8/0x1d0 ret_from_fork+0x10/0x18 There is also refcount issue, as well: WARNING: CPU: 1 PID: 1 at lib/refcount.c:28 refcount_warn_saturate+0xf8/0x170 The issue is that we make an erroneous extra call to scsi_host_put() for that host: So in ahci_init_one()->ata_host_alloc_pinfo()->ata_host_alloc(), we setup a device release method - ata_devres_release() - which intends to release the SCSI hosts: static void ata_devres_release(struct device *gendev, void *res) { ... for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; if (!ap) continue; if (ap->scsi_host) scsi_host_put(ap->scsi_host); } ... } However in the ata_scsi_add_hosts() error path, we also call scsi_host_put() for the SCSI hosts. Fix by removing the the scsi_host_put() calls in ata_scsi_add_hosts() and leave this to ata_devres_release(). Fixes: f31871951b38 ("libata: separate out ata_host_alloc() and ata_host_register()") Signed-off-by: John Garry Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index eb2eb599e602..061eebf85e6d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4562,22 +4562,19 @@ 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; } From 45b8084f3fcb9fe1a653fd49afa1fd7a5f0c10f2 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 22 Feb 2020 12:20:57 +0100 Subject: [PATCH 07/36] libata: Assign OF node to the SCSI device When we spawn a SCSI device from an ATA device in libata-scsi the SCSI device had no relation to the device tree. The DT binding allows us to define port nodes under a PATA (IDE) or SATA host controller, so we can have proper device nodes for these devices. If OF is enabled, walk the children of the host controller node to see if there is a valid device tree node to assign. The reg is used to match to ID 0 for the master device and ID 1 for the slave device. The corresponding device tree bindings have been accepted by the device tree maintainers. Cc: Chris Healy Cc: Martin K. Petersen Cc: Bart Van Assche Reviewed-by: Guenter Roeck Signed-off-by: Linus Walleij Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 061eebf85e6d..75bd7792df02 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "libata.h" #include "libata-transport.h" @@ -4579,6 +4580,34 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) 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; @@ -4604,6 +4633,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; From 5e125d13371b3049d238a4bf5f2108bfbfe8a900 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Feb 2020 17:32:59 +0300 Subject: [PATCH 08/36] ahci: Add Intel Comet Lake PCH-H PCI ID Add Intel Comet Lake PCH-H PCI ID to the list of supported controllers. Signed-off-by: Mika Westerberg Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2025b29f17fa..a25ed053d98e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -246,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 */ From 58c42b0b0d6eabb1db52f0f9e4b6017e81132055 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 28 Feb 2020 13:50:48 +0300 Subject: [PATCH 09/36] ahci: Add Intel Comet Lake PCH-V PCI ID Add Intel Comet Lake PCH-V PCI ID to the list of supported controllers. Signed-off-by: Mika Westerberg Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a25ed053d98e..ad0185c8dcee 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -404,6 +404,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { 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 */ From 3e1ee734ab3723df2227d570dbe5d9f14b13985c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:57:56 +0100 Subject: [PATCH 10/36] ata: remove stale maintainership information from core code In commit 7634ccd2da97 ("libata: maintainership update") from 2018 Jens has officially taken over libata maintainership from Tejun so remove stale information from core libata code. Acked-by: Tejun Heo Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 4 ---- drivers/ata/libata-eh.c | 4 ---- drivers/ata/libata-scsi.c | 4 ---- drivers/ata/libata-sff.c | 4 ---- 4 files changed, 16 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 42c8728f6117..4991f9d5def8 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2,10 +2,6 @@ /* * libata-core.c - helper library for ATA * - * Maintained by: Tejun Heo - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik * diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 3bfd9da58473..53605c8949d8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2,10 +2,6 @@ /* * libata-eh.c - libata error handling * - * Maintained by: Tejun Heo - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2006 Tejun Heo * * libata documentation is available via 'make {ps|pdf}docs', diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 75bd7792df02..ebc3de7c363a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2,10 +2,6 @@ /* * libata-scsi.c - helper library for ATA * - * Maintained by: Tejun Heo - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik * diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 038db94216a9..ae7189d1a568 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2,10 +2,6 @@ /* * libata-sff.c - helper library for PCI IDE BMDMA * - * Maintained by: Tejun Heo - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * * Copyright 2003-2006 Red Hat, Inc. All rights reserved. * Copyright 2003-2006 Jeff Garzik * From 6f09eae3b5d974ef845e56690d6bc2b8f2a70acd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:57:57 +0100 Subject: [PATCH 11/36] ata: expose ncq_enable_prio sysfs attribute only on NCQ capable hosts There is no point in exposing ncq_enable_prio sysfs attribute for devices on PATA and non-NCQ capable SATA hosts so: * remove dev_attr_ncq_prio_enable from ata_common_sdev_attrs[] * add ata_ncq_sdev_attrs[] * update ATA_NCQ_SHT() macro to use ata_ncq_sdev_attrs[] Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 8 +++++++- include/linux/libata.h | 11 ++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ebc3de7c363a..005c6f2f7d21 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -463,11 +463,17 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity); struct device_attribute *ata_common_sdev_attrs[] = { &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, NULL }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); +struct device_attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads, + &dev_attr_ncq_prio_enable, + NULL +}; +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); + /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined diff --git a/include/linux/libata.h b/include/linux/libata.h index 710e09dae910..350fa584acde 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1334,6 +1334,7 @@ extern int ata_link_nr_enabled(struct ata_link *link); extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; extern struct device_attribute *ata_common_sdev_attrs[]; +extern struct device_attribute *ata_ncq_sdev_attrs[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1341,7 +1342,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, \ @@ -1355,11 +1356,15 @@ 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 #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 /* From bd322af15ce970737c9b71fe2f368fea63ae70b9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:57:58 +0100 Subject: [PATCH 12/36] ata: make SATA_PMP option selectable only if any SATA host driver is enabled There is no reason to expose SATA_PMP config option when no SATA host drivers are enabled. To fix it add SATA_HOST config option, make all SATA host drivers select it and finally make SATA_PMP config options depend on it. This also serves as preparation for the future changes which optimize libata core code size on PATA only setups. CC: "James E.J. Bottomley" Reviewed-by: Martin K. Petersen # for SCSI bits Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/Kconfig | 40 +++++++++++++++++++++++++++++++++++++ drivers/scsi/Kconfig | 1 + drivers/scsi/libsas/Kconfig | 1 + 3 files changed, 42 insertions(+) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a6beb2c5a692..ad7760656f71 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -34,6 +34,9 @@ if ATA config ATA_NONSTANDARD bool +config SATA_HOST + bool + config ATA_VERBOSE_ERROR bool "Verbose ATA error reporting" default y @@ -73,6 +76,7 @@ config SATA_ZPODD config SATA_PMP bool "SATA Port Multiplier support" + depends on SATA_HOST default y help This option adds support for SATA Port Multipliers @@ -85,6 +89,7 @@ comment "Controllers with non-SFF native interface" config SATA_AHCI tristate "AHCI SATA support" depends on PCI + select SATA_HOST help This option enables support for AHCI Serial ATA. @@ -111,6 +116,7 @@ config SATA_MOBILE_LPM_POLICY config SATA_AHCI_PLATFORM tristate "Platform AHCI SATA support" + select SATA_HOST help This option enables support for Platform AHCI Serial ATA controllers. @@ -121,6 +127,7 @@ config AHCI_BRCM tristate "Broadcom AHCI SATA support" depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \ ARCH_BCM_63XX + select SATA_HOST help This option enables support for the AHCI SATA3 controller found on Broadcom SoC's. @@ -130,6 +137,7 @@ config AHCI_BRCM config AHCI_DA850 tristate "DaVinci DA850 AHCI SATA support" depends on ARCH_DAVINCI_DA850 + select SATA_HOST help This option enables support for the DaVinci DA850 SoC's onboard AHCI SATA. @@ -139,6 +147,7 @@ config AHCI_DA850 config AHCI_DM816 tristate "DaVinci DM816 AHCI SATA support" depends on ARCH_OMAP2PLUS + select SATA_HOST help This option enables support for the DaVinci DM816 SoC's onboard AHCI SATA controller. @@ -148,6 +157,7 @@ config AHCI_DM816 config AHCI_ST tristate "ST AHCI SATA support" depends on ARCH_STI + select SATA_HOST help This option enables support for ST AHCI SATA controller. @@ -157,6 +167,7 @@ config AHCI_IMX tristate "Freescale i.MX AHCI SATA support" depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON + select SATA_HOST help This option enables support for the Freescale i.MX SoC's onboard AHCI SATA. @@ -166,6 +177,7 @@ config AHCI_IMX config AHCI_CEVA tristate "CEVA AHCI SATA support" depends on OF + select SATA_HOST help This option enables support for the CEVA AHCI SATA. It can be found on the Xilinx Zynq UltraScale+ MPSoC. @@ -176,6 +188,7 @@ config AHCI_MTK tristate "MediaTek AHCI SATA support" depends on ARCH_MEDIATEK select MFD_SYSCON + select SATA_HOST help This option enables support for the MediaTek SoC's onboard AHCI SATA controller. @@ -185,6 +198,7 @@ config AHCI_MTK config AHCI_MVEBU tristate "Marvell EBU AHCI SATA support" depends on ARCH_MVEBU + select SATA_HOST help This option enables support for the Marvebu EBU SoC's onboard AHCI SATA. @@ -203,6 +217,7 @@ config AHCI_OCTEON config AHCI_SUNXI tristate "Allwinner sunxi AHCI SATA support" depends on ARCH_SUNXI + select SATA_HOST help This option enables support for the Allwinner sunxi SoC's onboard AHCI SATA. @@ -212,6 +227,7 @@ config AHCI_SUNXI config AHCI_TEGRA tristate "NVIDIA Tegra AHCI SATA support" depends on ARCH_TEGRA + select SATA_HOST help This option enables support for the NVIDIA Tegra SoC's onboard AHCI SATA. @@ -221,12 +237,14 @@ config AHCI_TEGRA config AHCI_XGENE tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" depends on PHY_XGENE + select SATA_HOST help This option enables support for APM X-Gene SoC SATA host controller. config AHCI_QORIQ tristate "Freescale QorIQ AHCI SATA support" depends on OF + select SATA_HOST help This option enables support for the Freescale QorIQ AHCI SoC's onboard AHCI SATA. @@ -236,6 +254,7 @@ config AHCI_QORIQ config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC + select SATA_HOST help This option enables support for Freescale 3.0Gbps SATA controller. It can be found on MPC837x and MPC8315. @@ -245,6 +264,7 @@ config SATA_FSL config SATA_GEMINI tristate "Gemini SATA bridge support" depends on ARCH_GEMINI || COMPILE_TEST + select SATA_HOST default ARCH_GEMINI help This enabled support for the FTIDE010 to SATA bridge @@ -255,6 +275,7 @@ config SATA_GEMINI config SATA_AHCI_SEATTLE tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" depends on ARCH_SEATTLE + select SATA_HOST help This option enables support for AMD Seattle SATA host controller. @@ -263,12 +284,14 @@ config SATA_AHCI_SEATTLE config SATA_INIC162X tristate "Initio 162x SATA support (Very Experimental)" depends on PCI + select SATA_HOST help This option enables support for Initio 162x Serial ATA. config SATA_ACARD_AHCI tristate "ACard AHCI variant (ATP 8620)" depends on PCI + select SATA_HOST help This option enables support for Acard. @@ -277,6 +300,7 @@ config SATA_ACARD_AHCI config SATA_SIL24 tristate "Silicon Image 3124/3132 SATA support" depends on PCI + select SATA_HOST help This option enables support for Silicon Image 3124/3132 Serial ATA. @@ -326,6 +350,7 @@ config PATA_OCTEON_CF config SATA_QSTOR tristate "Pacific Digital SATA QStor support" depends on PCI + select SATA_HOST help This option enables support for Pacific Digital Serial ATA QStor. @@ -334,6 +359,7 @@ config SATA_QSTOR config SATA_SX4 tristate "Promise SATA SX4 support (Experimental)" depends on PCI + select SATA_HOST help This option enables support for Promise Serial ATA SX4. @@ -357,6 +383,7 @@ comment "SATA SFF controllers with BMDMA" config ATA_PIIX tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" depends on PCI + select SATA_HOST help This option enables support for ICH5/6/7/8 Serial ATA and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series @@ -368,6 +395,7 @@ config SATA_DWC tristate "DesignWare Cores SATA support" depends on DMADEVICES select GENERIC_PHY + select SATA_HOST help This option enables support for the on-chip SATA controller of the AppliedMicro processor 460EX. @@ -398,6 +426,7 @@ config SATA_DWC_VDEBUG config SATA_HIGHBANK tristate "Calxeda Highbank SATA support" depends on ARCH_HIGHBANK || COMPILE_TEST + select SATA_HOST help This option enables support for the Calxeda Highbank SoC's onboard SATA. @@ -409,6 +438,7 @@ config SATA_MV depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \ ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST select GENERIC_PHY + select SATA_HOST help This option enables support for the Marvell Serial ATA family. Currently supports 88SX[56]0[48][01] PCI(-X) chips, @@ -419,6 +449,7 @@ config SATA_MV config SATA_NV tristate "NVIDIA SATA support" depends on PCI + select SATA_HOST help This option enables support for NVIDIA Serial ATA. @@ -427,6 +458,7 @@ config SATA_NV config SATA_PROMISE tristate "Promise SATA TX2/TX4 support" depends on PCI + select SATA_HOST help This option enables support for Promise Serial ATA TX2/TX4. @@ -435,6 +467,7 @@ config SATA_PROMISE config SATA_RCAR tristate "Renesas R-Car SATA support" depends on ARCH_RENESAS || COMPILE_TEST + select SATA_HOST help This option enables support for Renesas R-Car Serial ATA. @@ -443,6 +476,7 @@ config SATA_RCAR config SATA_SIL tristate "Silicon Image SATA support" depends on PCI + select SATA_HOST help This option enables support for Silicon Image Serial ATA. @@ -452,6 +486,7 @@ config SATA_SIS tristate "SiS 964/965/966/180 SATA support" depends on PCI select PATA_SIS + select SATA_HOST help This option enables support for SiS Serial ATA on SiS 964/965/966/180 and Parallel ATA on SiS 180. @@ -462,6 +497,7 @@ config SATA_SIS config SATA_SVW tristate "ServerWorks Frodo / Apple K2 SATA support" depends on PCI + select SATA_HOST help This option enables support for Broadcom/Serverworks/Apple K2 SATA support. @@ -471,6 +507,7 @@ config SATA_SVW config SATA_ULI tristate "ULi Electronics SATA support" depends on PCI + select SATA_HOST help This option enables support for ULi Electronics SATA. @@ -479,6 +516,7 @@ config SATA_ULI config SATA_VIA tristate "VIA SATA support" depends on PCI + select SATA_HOST help This option enables support for VIA Serial ATA. @@ -487,6 +525,7 @@ config SATA_VIA config SATA_VITESSE tristate "VITESSE VSC-7174 / INTEL 31244 SATA support" depends on PCI + select SATA_HOST help This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA. @@ -1113,6 +1152,7 @@ config PATA_ACPI config ATA_GENERIC tristate "Generic ATA support" depends on PCI && ATA_BMDMA + select SATA_HOST help This option enables support for generic BIOS configured ATA controllers via the new ATA layer diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a7881f8eb05e..1b6eaf8da5fa 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO config SCSI_IPR tristate "IBM Power Linux RAID adapter support" depends on PCI && SCSI && ATA + select SATA_HOST select FW_LOADER select IRQ_POLL select SGL_ALLOC diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig index 5c6a5eff2f8e..052ee3a26f6e 100644 --- a/drivers/scsi/libsas/Kconfig +++ b/drivers/scsi/libsas/Kconfig @@ -19,6 +19,7 @@ config SCSI_SAS_ATA bool "ATA support for libsas (requires libata)" depends on SCSI_SAS_LIBSAS depends on ATA = y || ATA = SCSI_SAS_LIBSAS + select SATA_HOST help Builds in ATA support into libsas. Will necessitate the loading of libata along with libsas. From 3f0998da55d662417ac115c22190f874cff7dd19 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:57:59 +0100 Subject: [PATCH 13/36] sata_promise: use ata_cable_sata() Use core helper instead of open-coding it. Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/sata_promise.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index c451d7d1c817..8729f78cef5f 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, static void pdc_error_handler(struct ata_port *ap); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static int pdc_pata_cable_detect(struct ata_port *ap); -static int pdc_sata_cable_detect(struct ata_port *ap); static struct scsi_host_template pdc_ata_sht = { ATA_BASE_SHT(DRV_NAME), @@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = { static struct ata_port_operations pdc_sata_ops = { .inherits = &pdc_common_ops, - .cable_detect = pdc_sata_cable_detect, + .cable_detect = ata_cable_sata, .freeze = pdc_sata_freeze, .thaw = pdc_sata_thaw, .scr_read = pdc_sata_scr_read, @@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } -static int pdc_sata_cable_detect(struct ata_port *ap) -{ - return ATA_CBL_SATA; -} - static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) { From 33531001364d32a79b34da2dd4089715384d0968 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:00 +0100 Subject: [PATCH 14/36] ata: simplify ata_scsiop_inq_89() Initialize rbuf[] directly instead of using ata_tf_to_fis(). This results in simpler and smaller code. It also allows separating ata_tf_to_fis() into SATA specific libata part in the future. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 20824 105 4096 25025 61c1 drivers/ata/libata-scsi.o after: 20782 105 4096 24983 6197 drivers/ata/libata-scsi.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 005c6f2f7d21..0912acb82b80 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2357,10 +2357,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); @@ -2369,14 +2365,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; From bbf5a0976dc3d0369ca4e6051ba09d681e3f7d7b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:01 +0100 Subject: [PATCH 15/36] ata: use COMMAND_LINE_SIZE for ata_force_param_buf[] size Use COMMAND_LINE_SIZE instead PAGE_SIZE for ata_force_param_buf[] size as libata parameters buffer doesn't need to be bigger than the command line buffer. For many architectures this results in decreased libata-core.o size (COMMAND_LINE_SIZE varies from 256 to 4096 while the minimum PAGE_SIZE is 4096). Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 41064 4413 40 45517 b1cd drivers/ata/libata-core.o after: 41064 573 40 41677 a2cd drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4991f9d5def8..a9a8762448aa 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -52,6 +52,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -106,7 +107,7 @@ struct ata_force_ent { static struct ata_force_ent *ata_force_tbl; static int ata_force_tbl_size; -static char ata_force_param_buf[PAGE_SIZE] __initdata; +static char ata_force_param_buf[COMMAND_LINE_SIZE] __initdata; /* param_buf is thrown away after initialization, disallow read */ module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/admin-guide/kernel-parameters.rst for details)"); From 8ba5a45c998cdbfb565fb7670782407c3e4a25ba Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:02 +0100 Subject: [PATCH 16/36] ata: optimize struct ata_force_param size Optimize struct ata_force_param size by: - using u8 for cbl and spd_limit fields - using u16 for lflags field Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 41064 573 40 41677 a2cd drivers/ata/libata-core.o after: 40654 573 40 41267 a133 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 6 +++--- include/linux/libata.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a9a8762448aa..a835d2bf243e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -90,12 +90,12 @@ atomic_t ata_print_id = ATOMIC_INIT(0); struct ata_force_param { const char *name; - unsigned int cbl; - int spd_limit; + u8 cbl; + u8 spd_limit; unsigned long xfer_mask; unsigned int horkage_on; unsigned int horkage_off; - unsigned int lflags; + u16 lflags; }; struct ata_force_ent { diff --git a/include/linux/libata.h b/include/linux/libata.h index 350fa584acde..236e4c55be48 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -174,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 */ From c8fa4f8e22d1308179dfe17abb00d3aebbcb7410 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:03 +0100 Subject: [PATCH 17/36] ata: optimize ata_scsi_rbuf[] size Currently the maximum required size of the ata_scsi_rbuf[] is 576 bytes in ata_scsiop_inq_89() so modify ATA_SCSI_RBUF_SIZE define accordingly. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 20782 105 4096 24983 6197 drivers/ata/libata-scsi.o after: 20782 105 576 21463 53d7 drivers/ata/libata-scsi.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0912acb82b80..c2b8428dfb94 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -37,7 +37,7 @@ #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]; From a52fbcfc7b38b50b5b651bab80041a93ba7b29b9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:04 +0100 Subject: [PATCH 18/36] ata: move EXPORT_SYMBOL_GPL()s close to exported code Move EXPORT_SYMBOL_GPL()s close to exported code like it is done in other kernel subsystems. As a nice side effect this results in the removal of few ifdefs. Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 208 +++++++++++++++----------------------- drivers/ata/libata-eh.c | 20 +++- drivers/ata/libata-scsi.c | 8 ++ 3 files changed, 109 insertions(+), 127 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a835d2bf243e..dc48e983ccdb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -18,6 +18,11 @@ * http://www.compactflash.org (CF) * http://www.qic.org (QIC157 - Tape and DSC) * http://www.ce-ata.org (CE-ATA: not supported) + * + * libata is essentially a library of internal helper functions for + * low-level ATA host controller drivers. As such, the API/ABI is + * likely to change as new drivers are added and updated. + * Do not depend on ABI/API stability. */ #include @@ -62,8 +67,11 @@ /* debounce timing parameters in msecs { interval, duration, timeout } */ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_normal); const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_long); const struct ata_port_operations ata_base_port_ops = { .prereset = ata_std_prereset, @@ -72,6 +80,7 @@ const struct ata_port_operations ata_base_port_ops = { .sched_eh = ata_std_sched_eh, .end_eh = ata_std_end_eh, }; +EXPORT_SYMBOL_GPL(ata_base_port_ops); const struct ata_port_operations sata_port_ops = { .inherits = &ata_base_port_ops, @@ -79,6 +88,7 @@ const struct ata_port_operations sata_port_ops = { .qc_defer = ata_std_qc_defer, .hardreset = sata_std_hardreset, }; +EXPORT_SYMBOL_GPL(sata_port_ops); static unsigned int ata_dev_init_params(struct ata_device *dev, u16 heads, u16 sectors); @@ -221,6 +231,7 @@ struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap, return NULL; } +EXPORT_SYMBOL_GPL(ata_link_next); /** * ata_dev_next - device iteration helper @@ -274,6 +285,7 @@ struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link, goto next; return dev; } +EXPORT_SYMBOL_GPL(ata_dev_next); /** * ata_dev_phys_link - find physical link for a device @@ -518,6 +530,7 @@ int atapi_cmd_type(u8 opcode) return ATAPI_MISC; } } +EXPORT_SYMBOL_GPL(atapi_cmd_type); /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure @@ -562,6 +575,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) fis[18] = (tf->auxiliary >> 16) & 0xff; fis[19] = (tf->auxiliary >> 24) & 0xff; } +EXPORT_SYMBOL_GPL(ata_tf_to_fis); /** * ata_tf_from_fis - Convert SATA FIS to ATA taskfile @@ -591,6 +605,7 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) tf->nsect = fis[12]; tf->hob_nsect = fis[13]; } +EXPORT_SYMBOL_GPL(ata_tf_from_fis); static const u8 ata_rw_cmds[] = { /* pio multi */ @@ -865,6 +880,7 @@ unsigned long ata_pack_xfermask(unsigned long pio_mask, ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); } +EXPORT_SYMBOL_GPL(ata_pack_xfermask); /** * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks @@ -886,6 +902,7 @@ void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask, if (udma_mask) *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; } +EXPORT_SYMBOL_GPL(ata_unpack_xfermask); static const struct ata_xfer_ent { int shift, bits; @@ -920,6 +937,7 @@ u8 ata_xfer_mask2mode(unsigned long xfer_mask) return ent->base + highbit - ent->shift; return 0xff; } +EXPORT_SYMBOL_GPL(ata_xfer_mask2mode); /** * ata_xfer_mode2mask - Find matching xfer_mask for XFER_* @@ -943,6 +961,7 @@ unsigned long ata_xfer_mode2mask(u8 xfer_mode) & ~((1 << ent->shift) - 1); return 0; } +EXPORT_SYMBOL_GPL(ata_xfer_mode2mask); /** * ata_xfer_mode2shift - Find matching xfer_shift for XFER_* @@ -965,6 +984,7 @@ int ata_xfer_mode2shift(unsigned long xfer_mode) return ent->shift; return -1; } +EXPORT_SYMBOL_GPL(ata_xfer_mode2shift); /** * ata_mode_string - convert xfer_mask to string @@ -1011,6 +1031,7 @@ const char *ata_mode_string(unsigned long xfer_mask) return xfer_mode_str[highbit]; return ""; } +EXPORT_SYMBOL_GPL(ata_mode_string); const char *sata_spd_string(unsigned int spd) { @@ -1091,6 +1112,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) DPRINTK("unknown device\n"); return ATA_DEV_UNKNOWN; } +EXPORT_SYMBOL_GPL(ata_dev_classify); /** * ata_id_string - Convert IDENTIFY DEVICE page into string @@ -1127,6 +1149,7 @@ void ata_id_string(const u16 *id, unsigned char *s, len -= 2; } } +EXPORT_SYMBOL_GPL(ata_id_string); /** * ata_id_c_string - Convert IDENTIFY DEVICE page into C string @@ -1154,6 +1177,7 @@ void ata_id_c_string(const u16 *id, unsigned char *s, p--; *p = '\0'; } +EXPORT_SYMBOL_GPL(ata_id_c_string); static u64 ata_id_n_sectors(const u16 *id) { @@ -1511,6 +1535,7 @@ unsigned long ata_id_xfermask(const u16 *id) return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); } +EXPORT_SYMBOL_GPL(ata_id_xfermask); static void ata_qc_complete_internal(struct ata_queued_cmd *qc) { @@ -1768,6 +1793,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) return 1; return 0; } +EXPORT_SYMBOL_GPL(ata_pio_need_iordy); /** * ata_pio_mask_no_iordy - Return the non IORDY mask @@ -1808,6 +1834,7 @@ unsigned int ata_do_dev_read_id(struct ata_device *dev, return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, sizeof(id[0]) * ATA_ID_WORDS, 0); } +EXPORT_SYMBOL_GPL(ata_do_dev_read_id); /** * ata_dev_read_id - Read ID data from the specified device @@ -2780,6 +2807,7 @@ int ata_cable_40wire(struct ata_port *ap) { return ATA_CBL_PATA40; } +EXPORT_SYMBOL_GPL(ata_cable_40wire); /** * ata_cable_80wire - return 80 wire cable type @@ -2793,6 +2821,7 @@ int ata_cable_80wire(struct ata_port *ap) { return ATA_CBL_PATA80; } +EXPORT_SYMBOL_GPL(ata_cable_80wire); /** * ata_cable_unknown - return unknown PATA cable. @@ -2805,6 +2834,7 @@ int ata_cable_unknown(struct ata_port *ap) { return ATA_CBL_PATA_UNK; } +EXPORT_SYMBOL_GPL(ata_cable_unknown); /** * ata_cable_ignore - return ignored PATA cable. @@ -2817,6 +2847,7 @@ int ata_cable_ignore(struct ata_port *ap) { return ATA_CBL_PATA_IGN; } +EXPORT_SYMBOL_GPL(ata_cable_ignore); /** * ata_cable_sata - return SATA cable type @@ -2829,6 +2860,7 @@ int ata_cable_sata(struct ata_port *ap) { return ATA_CBL_SATA; } +EXPORT_SYMBOL_GPL(ata_cable_sata); /** * ata_bus_probe - Reset and probe ATA bus @@ -3011,6 +3043,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) return NULL; return pair; } +EXPORT_SYMBOL_GPL(ata_dev_pair); /** * sata_down_spd_limit - adjust SATA spd limit downward @@ -3171,6 +3204,7 @@ int sata_set_spd(struct ata_link *link) return 1; } +EXPORT_SYMBOL_GPL(sata_set_spd); /* * This mode timing computation functionality is ported over from @@ -3245,6 +3279,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); } +EXPORT_SYMBOL_GPL(ata_timing_merge); const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) { @@ -3261,6 +3296,7 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) return NULL; } +EXPORT_SYMBOL_GPL(ata_timing_find_mode); int ata_timing_compute(struct ata_device *adev, unsigned short speed, struct ata_timing *t, int T, int UT) @@ -3337,6 +3373,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, return 0; } +EXPORT_SYMBOL_GPL(ata_timing_compute); /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration @@ -3388,6 +3425,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } +EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); /** * ata_down_xfermask_limit - adjust dev xfer masks downward @@ -3659,6 +3697,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) *r_failed_dev = dev; return rc; } +EXPORT_SYMBOL_GPL(ata_do_set_mode); /** * ata_wait_ready - wait for link to become ready @@ -3768,6 +3807,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, return ata_wait_ready(link, deadline, check_ready); } +EXPORT_SYMBOL_GPL(ata_wait_after_reset); /** * sata_link_debounce - debounce SATA phy status @@ -3838,6 +3878,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, return -EPIPE; } } +EXPORT_SYMBOL_GPL(sata_link_debounce); /** * sata_link_resume - resume SATA link @@ -3904,6 +3945,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, return rc != -EINVAL ? rc : 0; } +EXPORT_SYMBOL_GPL(sata_link_resume); /** * sata_link_scr_lpm - manipulate SControl IPM and SPM fields @@ -3978,6 +4020,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, ehc->i.serror &= ~SERR_PHYRDY_CHG; return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); } +EXPORT_SYMBOL_GPL(sata_link_scr_lpm); /** * ata_std_prereset - prepare for reset @@ -4023,6 +4066,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) return 0; } +EXPORT_SYMBOL_GPL(ata_std_prereset); /** * sata_link_hardreset - reset link via SATA phy reset @@ -4135,6 +4179,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, DPRINTK("EXIT, rc=%d\n", rc); return rc; } +EXPORT_SYMBOL_GPL(sata_link_hardreset); /** * sata_std_hardreset - COMRESET w/o waiting or classification @@ -4161,6 +4206,7 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, rc = sata_link_hardreset(link, timing, deadline, &online, NULL); return online ? -EAGAIN : rc; } +EXPORT_SYMBOL_GPL(sata_std_hardreset); /** * ata_std_postreset - standard postreset callback @@ -4189,6 +4235,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) DPRINTK("EXIT\n"); } +EXPORT_SYMBOL_GPL(ata_std_postreset); /** * ata_dev_same_device - Determine whether new ID matches configured device @@ -4976,11 +5023,13 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) return ATA_DEFER_LINK; } +EXPORT_SYMBOL_GPL(ata_std_qc_defer); enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc) { return AC_ERR_OK; } +EXPORT_SYMBOL_GPL(ata_noop_qc_prep); /** * ata_sg_init - Associate command with scatter-gather table. @@ -5002,6 +5051,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->n_elem = n_elem; qc->cursg = qc->sg; } +EXPORT_SYMBOL_GPL(ata_sg_init); #ifdef CONFIG_HAS_DMA @@ -5324,6 +5374,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) __ata_qc_complete(qc); } } +EXPORT_SYMBOL_GPL(ata_qc_complete); /** * ata_qc_get_active - get bitmask of active qcs @@ -5406,6 +5457,7 @@ int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) return nr_done; } +EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); /** * ata_qc_issue - issue taskfile to device @@ -5500,6 +5552,7 @@ int sata_scr_valid(struct ata_link *link) return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read; } +EXPORT_SYMBOL_GPL(sata_scr_valid); /** * sata_scr_read - read SCR register of the specified port @@ -5527,6 +5580,7 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val) return sata_pmp_scr_read(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_read); /** * sata_scr_write - write SCR register of the specified port @@ -5554,6 +5608,7 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val) return sata_pmp_scr_write(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_write); /** * sata_scr_write_flush - write SCR register of the specified port and flush @@ -5586,6 +5641,7 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) return sata_pmp_scr_write(link, reg, val); } +EXPORT_SYMBOL_GPL(sata_scr_write_flush); /** * ata_phys_link_online - test whether the given link is online @@ -5660,6 +5716,7 @@ bool ata_link_online(struct ata_link *link) return ata_phys_link_online(link) || (slave && ata_phys_link_online(slave)); } +EXPORT_SYMBOL_GPL(ata_link_online); /** * ata_link_offline - test whether the given link is offline @@ -5686,6 +5743,7 @@ bool ata_link_offline(struct ata_link *link) return ata_phys_link_offline(link) && (!slave || ata_phys_link_offline(slave)); } +EXPORT_SYMBOL_GPL(ata_link_offline); #ifdef CONFIG_PM static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, @@ -5872,6 +5930,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) host->dev->power.power_state = mesg; return 0; } +EXPORT_SYMBOL_GPL(ata_host_suspend); /** * ata_host_resume - resume host @@ -5883,6 +5942,7 @@ void ata_host_resume(struct ata_host *host) { host->dev->power.power_state = PMSG_ON; } +EXPORT_SYMBOL_GPL(ata_host_resume); #endif const struct device_type ata_port_type = { @@ -6097,11 +6157,13 @@ void ata_host_get(struct ata_host *host) { kref_get(&host->kref); } +EXPORT_SYMBOL_GPL(ata_host_get); void ata_host_put(struct ata_host *host) { kref_put(&host->kref, ata_host_release); } +EXPORT_SYMBOL_GPL(ata_host_put); /** * ata_host_alloc - allocate and init basic ATA host resources @@ -6175,6 +6237,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) kfree(host); return NULL; } +EXPORT_SYMBOL_GPL(ata_host_alloc); /** * ata_host_alloc_pinfo - alloc host and init with port_info array @@ -6223,6 +6286,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, return host; } +EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); /** * ata_slave_link_init - initialize slave link @@ -6285,6 +6349,7 @@ int ata_slave_link_init(struct ata_port *ap) ap->slave_link = link; return 0; } +EXPORT_SYMBOL_GPL(ata_slave_link_init); static void ata_host_stop(struct device *gendev, void *res) { @@ -6433,6 +6498,7 @@ int ata_host_start(struct ata_host *host) devres_free(start_dr); return rc; } +EXPORT_SYMBOL_GPL(ata_host_start); /** * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas) @@ -6451,6 +6517,7 @@ void ata_host_init(struct ata_host *host, struct device *dev, host->ops = ops; kref_init(&host->kref); } +EXPORT_SYMBOL_GPL(ata_host_init); void __ata_port_probe(struct ata_port *ap) { @@ -6606,6 +6673,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) return rc; } +EXPORT_SYMBOL_GPL(ata_host_register); /** * ata_host_activate - start host, request IRQ and register it @@ -6668,6 +6736,7 @@ int ata_host_activate(struct ata_host *host, int irq, return rc; } +EXPORT_SYMBOL_GPL(ata_host_activate); /** * ata_port_detach - Detach ATA port in preparation of device removal @@ -6743,6 +6812,7 @@ void ata_host_detach(struct ata_host *host) /* the host is dead now, dissociate ACPI */ ata_acpi_dissociate(host); } +EXPORT_SYMBOL_GPL(ata_host_detach); #ifdef CONFIG_PCI @@ -6763,6 +6833,7 @@ void ata_pci_remove_one(struct pci_dev *pdev) ata_host_detach(host); } +EXPORT_SYMBOL_GPL(ata_pci_remove_one); void ata_pci_shutdown_one(struct pci_dev *pdev) { @@ -6783,6 +6854,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) @@ -6817,6 +6889,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) @@ -6827,6 +6900,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) { @@ -6845,6 +6919,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) { @@ -6859,6 +6934,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) { @@ -6870,8 +6946,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 */ /** @@ -6893,6 +6969,7 @@ int ata_platform_remove_one(struct platform_device *pdev) return 0; } +EXPORT_SYMBOL_GPL(ata_platform_remove_one); static int __init ata_parse_force_one(char **cur, struct ata_force_ent *force_ent, @@ -7117,6 +7194,7 @@ int ata_ratelimit(void) { return __ratelimit(&ratelimit); } +EXPORT_SYMBOL_GPL(ata_ratelimit); /** * ata_msleep - ATA EH owner aware msleep @@ -7149,6 +7227,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 @@ -7195,6 +7274,7 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, return tmp; } +EXPORT_SYMBOL_GPL(ata_wait_register); /** * sata_lpm_ignore_phy_events - test if PHY event should be ignored @@ -7248,10 +7328,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 @@ -7319,127 +7401,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); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 53605c8949d8..1d231cfab26f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -180,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) __ata_ehi_pushv_desc(ehi, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); /** * ata_ehi_push_desc - push error description with separator @@ -203,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) __ata_ehi_pushv_desc(ehi, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(ata_ehi_push_desc); /** * ata_ehi_clear_desc - clean error description @@ -218,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi) ehi->desc[0] = '\0'; ehi->desc_len = 0; } +EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); /** * ata_port_desc - append port description @@ -245,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...) __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); va_end(args); } +EXPORT_SYMBOL_GPL(ata_port_desc); #ifdef CONFIG_PCI - /** * ata_port_pbar_desc - append PCI BAR description * @ap: target ATA port @@ -284,7 +287,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, ata_port_desc(ap, "%s 0x%llx", name, start + (unsigned long long)offset); } - +EXPORT_SYMBOL_GPL(ata_port_pbar_desc); #endif /* CONFIG_PCI */ static int ata_lookup_timeout_table(u8 cmd) @@ -969,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap) /* see: ata_std_sched_eh, unless you know better */ ap->ops->sched_eh(ap); } +EXPORT_SYMBOL_GPL(ata_port_schedule_eh); static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) { @@ -1011,6 +1015,7 @@ int ata_link_abort(struct ata_link *link) { return ata_do_link_abort(link->ap, link); } +EXPORT_SYMBOL_GPL(ata_link_abort); /** * ata_port_abort - abort all qc's on the port @@ -1028,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap) { return ata_do_link_abort(ap, NULL); } +EXPORT_SYMBOL_GPL(ata_port_abort); /** * __ata_port_freeze - freeze port @@ -1084,6 +1090,7 @@ int ata_port_freeze(struct ata_port *ap) return nr_aborted; } +EXPORT_SYMBOL_GPL(ata_port_freeze); /** * sata_async_notification - SATA async notification handler @@ -1157,6 +1164,7 @@ int sata_async_notification(struct ata_port *ap) return 0; } } +EXPORT_SYMBOL_GPL(sata_async_notification); /** * ata_eh_freeze_port - EH helper to freeze port @@ -1178,6 +1186,7 @@ void ata_eh_freeze_port(struct ata_port *ap) __ata_port_freeze(ap); spin_unlock_irqrestore(ap->lock, flags); } +EXPORT_SYMBOL_GPL(ata_eh_freeze_port); /** * ata_port_thaw_port - EH helper to thaw port @@ -1206,6 +1215,7 @@ void ata_eh_thaw_port(struct ata_port *ap) DPRINTK("ata%u port thawed\n", ap->print_id); } +EXPORT_SYMBOL_GPL(ata_eh_thaw_port); static void ata_eh_scsidone(struct scsi_cmnd *scmd) { @@ -1240,6 +1250,7 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc) scmd->retries = scmd->allowed; __ata_eh_qc_complete(qc); } +EXPORT_SYMBOL_GPL(ata_eh_qc_complete); /** * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH @@ -1259,6 +1270,7 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) scmd->allowed++; __ata_eh_qc_complete(qc); } +EXPORT_SYMBOL_GPL(ata_eh_qc_retry); /** * ata_dev_disable - disable ATA device @@ -1285,6 +1297,7 @@ void ata_dev_disable(struct ata_device *dev) */ ata_ering_clear(&dev->ering); } +EXPORT_SYMBOL_GPL(ata_dev_disable); /** * ata_eh_detach_dev - detach ATA device @@ -1727,6 +1740,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ehc->i.err_mask &= ~AC_ERR_DEV; } +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); /** * ata_eh_analyze_tf - analyze taskfile of a failed qc @@ -4027,6 +4041,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } +EXPORT_SYMBOL_GPL(ata_do_eh); /** * ata_std_error_handler - standard error handler @@ -4048,6 +4063,7 @@ void ata_std_error_handler(struct ata_port *ap) ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); } +EXPORT_SYMBOL_GPL(ata_std_error_handler); #ifdef CONFIG_PM /** diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c2b8428dfb94..24024e728296 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -502,6 +502,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 @@ -531,6 +532,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 @@ -1347,6 +1349,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 @@ -1386,6 +1389,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) q->dma_drain_buffer = NULL; q->dma_drain_size = 0; } +EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); /** * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth @@ -1429,6 +1433,7 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, return scsi_change_queue_depth(sdev, queue_depth); } +EXPORT_SYMBOL_GPL(__ata_change_queue_depth); /** * ata_scsi_change_queue_depth - SCSI callback for queue depth config @@ -1451,6 +1456,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) return __ata_change_queue_depth(ap, sdev, queue_depth); } +EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); /** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command @@ -4406,6 +4412,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 @@ -4529,6 +4536,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } +EXPORT_SYMBOL_GPL(ata_scsi_simulate); int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) { From 2b67a6d3a4d2f630cd5e29b4bfe21a697585eaf8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:05 +0100 Subject: [PATCH 19/36] ata: remove EXPORT_SYMBOL_GPL()s not used by modules Remove EXPORT_SYMBOL_GPL()s for functions used only by the core libata code. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 39838 573 40 40451 9e03 drivers/ata/libata-core.o 21071 105 576 21752 54f8 drivers/ata/libata-scsi.o 17519 18 0 17537 4481 drivers/ata/libata-eh.o after: 39688 573 40 40301 9d6d drivers/ata/libata-core.o 21040 105 576 21721 54d9 drivers/ata/libata-scsi.o 17405 18 0 17423 440f drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 5 ----- drivers/ata/libata-eh.c | 4 ---- drivers/ata/libata-scsi.c | 1 - 3 files changed, 10 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dc48e983ccdb..2ec1a49388ee 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -80,7 +80,6 @@ const struct ata_port_operations ata_base_port_ops = { .sched_eh = ata_std_sched_eh, .end_eh = ata_std_end_eh, }; -EXPORT_SYMBOL_GPL(ata_base_port_ops); const struct ata_port_operations sata_port_ops = { .inherits = &ata_base_port_ops, @@ -902,7 +901,6 @@ void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask, if (udma_mask) *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; } -EXPORT_SYMBOL_GPL(ata_unpack_xfermask); static const struct ata_xfer_ent { int shift, bits; @@ -3425,7 +3423,6 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } -EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); /** * ata_down_xfermask_limit - adjust dev xfer masks downward @@ -5051,7 +5048,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->n_elem = n_elem; qc->cursg = qc->sg; } -EXPORT_SYMBOL_GPL(ata_sg_init); #ifdef CONFIG_HAS_DMA @@ -6157,7 +6153,6 @@ void ata_host_get(struct ata_host *host) { kref_get(&host->kref); } -EXPORT_SYMBOL_GPL(ata_host_get); void ata_host_put(struct ata_host *host) { diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1d231cfab26f..04275f4c8d36 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1215,7 +1215,6 @@ void ata_eh_thaw_port(struct ata_port *ap) DPRINTK("ata%u port thawed\n", ap->print_id); } -EXPORT_SYMBOL_GPL(ata_eh_thaw_port); static void ata_eh_scsidone(struct scsi_cmnd *scmd) { @@ -1250,7 +1249,6 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc) scmd->retries = scmd->allowed; __ata_eh_qc_complete(qc); } -EXPORT_SYMBOL_GPL(ata_eh_qc_complete); /** * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH @@ -1270,7 +1268,6 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) scmd->allowed++; __ata_eh_qc_complete(qc); } -EXPORT_SYMBOL_GPL(ata_eh_qc_retry); /** * ata_dev_disable - disable ATA device @@ -4041,7 +4038,6 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } -EXPORT_SYMBOL_GPL(ata_do_eh); /** * ata_std_error_handler - standard error handler diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 24024e728296..ae63ef7adcb9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4536,7 +4536,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } -EXPORT_SYMBOL_GPL(ata_scsi_simulate); int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) { From 4e168187047bf5d95b66567061007b87c29f7341 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:06 +0100 Subject: [PATCH 20/36] ata: fix CodingStyle issues in PATA timings code * fix the overly long line in ata_timing_quantize() * use standard kernel CodingStyle in ata_timing_merge() * do not use assignment in if condition in ata_timing_compute() * fix non-standard comment style in ata_timing_compute() Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2ec1a49388ee..acdcedcb3d10 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3251,7 +3251,8 @@ static const struct ata_timing ata_timing[] = { #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) +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); @@ -3267,15 +3268,24 @@ static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q 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); + 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); @@ -3306,8 +3316,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, /* * Find the mode. */ - - if (!(s = ata_timing_find_mode(speed))) + s = ata_timing_find_mode(speed); + if (!s) return -EINVAL; memcpy(t, s, sizeof(*s)); @@ -3363,9 +3373,11 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, 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 */ + /* + * 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; From a9b2c120e34bcfe49f837830ee4bfbd2aad4b5c8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:07 +0100 Subject: [PATCH 21/36] ata: separate PATA timings code from libata-core.c Separate PATA timings code from libata-core.c: * add PATA_TIMINGS config option and make corresponding PATA host drivers (and ATA ACPI code) select it * move following PATA timings code to libata-pata-timings.c: - ata_timing_quantize() - ata_timing_merge() - ata_timing_find_mode() - ata_timing_compute() * group above functions together in * include libata-pata-timings.c in the build when PATA_TIMINGS config option is enabled * cover ata_timing_cycle2mode() with CONFIG_ATA_ACPI ifdef (it depends on code from libata-core.c and libata-pata-timings.c while its only user is ATA ACPI) Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 39688 573 40 40301 9d6d drivers/ata/libata-core.o after: 37820 572 40 38432 9620 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/Kconfig | 21 ++++ drivers/ata/Makefile | 1 + drivers/ata/libata-core.c | 183 +--------------------------- drivers/ata/libata-pata-timings.c | 192 ++++++++++++++++++++++++++++++ include/linux/libata.h | 16 ++- 5 files changed, 226 insertions(+), 187 deletions(-) create mode 100644 drivers/ata/libata-pata-timings.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ad7760656f71..5b55ebf56b5a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -37,6 +37,9 @@ config ATA_NONSTANDARD config SATA_HOST bool +config PATA_TIMINGS + bool + config ATA_VERBOSE_ERROR bool "Verbose ATA error reporting" default y @@ -51,6 +54,7 @@ config ATA_VERBOSE_ERROR config ATA_ACPI bool "ATA ACPI Support" depends on ACPI + select PATA_TIMINGS default y help This option adds support for ATA-related ACPI objects. @@ -341,6 +345,7 @@ config PDC_ADMA config PATA_OCTEON_CF tristate "OCTEON Boot Bus Compact Flash support" depends on CAVIUM_OCTEON_SOC + select PATA_TIMINGS help This option enables a polled compact flash driver for use with compact flash cards attached to the OCTEON boot bus. @@ -536,6 +541,7 @@ comment "PATA SFF controllers with BMDMA" config PATA_ALI tristate "ALi PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the ALi ATA interfaces found on the many ALi chipsets. @@ -545,6 +551,7 @@ config PATA_ALI config PATA_AMD tristate "AMD/NVidia PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the AMD and NVidia PATA interfaces found on the chipsets for Athlon/Athlon64. @@ -579,6 +586,7 @@ config PATA_ATIIXP config PATA_ATP867X tristate "ARTOP/Acard ATP867X PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for ARTOP/Acard ATP867X PATA controllers. @@ -588,6 +596,7 @@ config PATA_ATP867X config PATA_BK3710 tristate "Palmchip BK3710 PATA support" depends on ARCH_DAVINCI + select PATA_TIMINGS help This option enables support for the integrated IDE controller on the TI DaVinci SoC. @@ -597,6 +606,7 @@ config PATA_BK3710 config PATA_CMD64X tristate "CMD64x PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the CMD64x series chips except for the CMD640. @@ -642,6 +652,7 @@ config PATA_CS5536 config PATA_CYPRESS tristate "Cypress CY82C693 PATA support (Very Experimental)" depends on PCI + select PATA_TIMINGS help This option enables support for the Cypress/Contaq CY82C693 chipset found in some Alpha systems @@ -660,6 +671,7 @@ config PATA_EFAR config PATA_EP93XX tristate "Cirrus Logic EP93xx PATA support" depends on ARCH_EP93XX + select PATA_TIMINGS help This option enables support for the PATA controller in the Cirrus Logic EP9312 and EP9315 ARM CPU. @@ -724,6 +736,7 @@ config PATA_HPT3X3_DMA config PATA_ICSIDE tristate "Acorn ICS PATA support" depends on ARM && ARCH_ACORN + select PATA_TIMINGS help On Acorn systems, say Y here if you wish to use the ICS PATA interface card. This is not required for ICS partition support. @@ -732,6 +745,7 @@ config PATA_ICSIDE config PATA_IMX tristate "PATA support for Freescale iMX" depends on ARCH_MXC + select PATA_TIMINGS help This option enables support for the PATA host available on Freescale iMX SoCs. @@ -817,6 +831,7 @@ config PATA_NINJA32 config PATA_NS87415 tristate "Nat Semi NS87415 PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the National Semiconductor NS87415 PCI-IDE controller. @@ -941,6 +956,7 @@ config PATA_TRIFLEX config PATA_VIA tristate "VIA PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the VIA PATA interfaces found on the many VIA chipsets. @@ -974,6 +990,7 @@ comment "PIO-only SFF controllers" config PATA_CMD640_PCI tristate "CMD640 PCI PATA support (Experimental)" depends on PCI + select PATA_TIMINGS help This option enables support for the CMD640 PCI IDE interface chip. Only the primary channel is currently @@ -1044,6 +1061,7 @@ config PATA_MPIIX config PATA_NS87410 tristate "Nat Semi NS87410 PATA support" depends on PCI + select PATA_TIMINGS help This option enables support for the National Semiconductor NS87410 PCI-IDE controller. @@ -1124,6 +1142,7 @@ config PATA_RZ1000 config PATA_SAMSUNG_CF tristate "Samsung SoC PATA support" depends on SAMSUNG_DEV_IDE + select PATA_TIMINGS help This option enables basic support for Samsung's S3C/S5P board PATA controllers via the new ATA layer @@ -1143,6 +1162,7 @@ comment "Generic fallback / legacy drivers" config PATA_ACPI tristate "ACPI firmware driver for PATA" depends on ATA_ACPI && ATA_BMDMA && PCI + select PATA_TIMINGS help This option enables an ACPI method driver which drives motherboard PATA controller interfaces through the ACPI @@ -1162,6 +1182,7 @@ config ATA_GENERIC config PATA_LEGACY tristate "Legacy ISA PATA support (Experimental)" depends on (ISA || PCI) + select PATA_TIMINGS help This option enables support for ISA/VLB/PCI bus legacy PATA ports and allows them to be accessed via the new ATA layer. diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d8cc2e04a6c7..cdaf965fed25 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -127,3 +127,4 @@ libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o +libata-$(CONFIG_PATA_TIMINGS) += libata-pata-timings.o diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index acdcedcb3d10..0a56968e2e98 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3204,187 +3204,7 @@ int sata_set_spd(struct ata_link *link) } EXPORT_SYMBOL_GPL(sata_set_spd); -/* - * This mode timing computation functionality is ported over from - * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik - */ -/* - * PIO 0-4, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). - * These were taken from ATA/ATAPI-6 standard, rev 0a, except - * for UDMA6, which is currently supported only by Maxtor drives. - * - * For PIO 5/6 MWDMA 3/4 see the CFA specification 3.0. - */ - -static const struct ata_timing ata_timing[] = { -/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */ - { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 }, - { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 }, - { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 }, - { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 }, - { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 }, - { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 }, - { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 }, - - { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 }, - { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 }, - { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 }, - - { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 }, - { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 }, - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 }, - { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 }, - { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 }, - -/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */ - { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 }, - { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 }, - { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 }, - { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 }, - { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 }, - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 }, - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 }, - - { 0xFF } -}; - -#define ENOUGH(v, unit) (((v)-1)/(unit)+1) -#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0) - -static void ata_timing_quantize(const struct ata_timing *t, - struct ata_timing *q, int T, int UT) -{ - q->setup = EZ(t->setup, T); - q->act8b = EZ(t->act8b, T); - q->rec8b = EZ(t->rec8b, T); - q->cyc8b = EZ(t->cyc8b, T); - q->active = EZ(t->active, T); - q->recover = EZ(t->recover, T); - q->dmack_hold = EZ(t->dmack_hold, T); - q->cycle = EZ(t->cycle, T); - q->udma = EZ(t->udma, UT); -} - -void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, - struct ata_timing *m, unsigned int what) -{ - if (what & ATA_TIMING_SETUP) - m->setup = max(a->setup, b->setup); - if (what & ATA_TIMING_ACT8B) - m->act8b = max(a->act8b, b->act8b); - if (what & ATA_TIMING_REC8B) - m->rec8b = max(a->rec8b, b->rec8b); - if (what & ATA_TIMING_CYC8B) - m->cyc8b = max(a->cyc8b, b->cyc8b); - if (what & ATA_TIMING_ACTIVE) - m->active = max(a->active, b->active); - if (what & ATA_TIMING_RECOVER) - m->recover = max(a->recover, b->recover); - if (what & ATA_TIMING_DMACK_HOLD) - m->dmack_hold = max(a->dmack_hold, b->dmack_hold); - if (what & ATA_TIMING_CYCLE) - m->cycle = max(a->cycle, b->cycle); - if (what & ATA_TIMING_UDMA) - m->udma = max(a->udma, b->udma); -} -EXPORT_SYMBOL_GPL(ata_timing_merge); - -const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) -{ - const struct ata_timing *t = ata_timing; - - while (xfer_mode > t->mode) - t++; - - if (xfer_mode == t->mode) - return t; - - WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", - __func__, xfer_mode); - - return NULL; -} -EXPORT_SYMBOL_GPL(ata_timing_find_mode); - -int ata_timing_compute(struct ata_device *adev, unsigned short speed, - struct ata_timing *t, int T, int UT) -{ - const u16 *id = adev->id; - const struct ata_timing *s; - struct ata_timing p; - - /* - * Find the mode. - */ - 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); - +#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. @@ -3435,6 +3255,7 @@ u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) return last_mode; } +#endif /** * ata_down_xfermask_limit - adjust dev xfer masks downward diff --git a/drivers/ata/libata-pata-timings.c b/drivers/ata/libata-pata-timings.c new file mode 100644 index 000000000000..af341226cc64 --- /dev/null +++ b/drivers/ata/libata-pata-timings.c @@ -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 +#include +#include + +/* + * 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/include/linux/libata.h b/include/linux/libata.h index 236e4c55be48..500b709ed3de 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1205,12 +1205,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 */ @@ -1807,6 +1801,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 */ From 7caa30ea8238aed4f9998d032bfca7a91f6c36cd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:08 +0100 Subject: [PATCH 22/36] ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled() When CONFIG_SATA_HOST=n there are no NCQ capable host drivers built so it is safe to hardwire ata_ncq_enabled() to always return zero. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 37820 572 40 38432 9620 drivers/ata/libata-core.o 21040 105 576 21721 54d9 drivers/ata/libata-scsi.o 17405 18 0 17423 440f drivers/ata/libata-eh.o after: 37582 572 40 38194 9532 drivers/ata/libata-core.o 20702 105 576 21383 5387 drivers/ata/libata-scsi.o 17353 18 0 17371 43db drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/libata.h b/include/linux/libata.h index 500b709ed3de..661d76038684 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1633,6 +1633,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; } From cba97ea18d92f3b9c56816fe9325aeb38a46746f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:09 +0100 Subject: [PATCH 23/36] ata: let compiler optimize out ata_dev_config_ncq() on non-SATA hosts Add !IS_ENABLED(CONFIG_SATA_HOST) to ata_dev_config_ncq() to allow compiler to optimize out the function for non-SATA configs. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 37582 572 40 38194 9532 drivers/ata/libata-core.o after: 36462 572 40 37074 90d2 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0a56968e2e98..dcdb7fb46dbd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2287,6 +2287,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; From 4c9029e7d00f31923bcecbaab6a12ba52017924e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:10 +0100 Subject: [PATCH 24/36] ata: let compiler optimize out ata_eh_set_lpm() on non-SATA hosts Add !IS_ENABLED(CONFIG_SATA_HOST) to ata_eh_set_lpm() to allow compiler to optimize out the function for non-SATA configs (for PATA hosts "ap && !ap->ops->set_lpm" condition is always true so it's sufficient for the function to return zero). Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 17353 18 0 17371 43db drivers/ata/libata-eh.o after: 16607 18 0 16625 40f1 drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-eh.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 04275f4c8d36..8dc33b6832f0 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3443,7 +3443,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; /* From 7fe183c773c42f9814cd361c45a0233f441bc4fc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:11 +0100 Subject: [PATCH 25/36] ata: start separating SATA specific code from libata-core.c Start separating SATA specific code from libata-core.c: * move following functions to libata-sata.c: - ata_tf_to_fis() - ata_tf_from_fis() - sata_link_scr_lpm() - ata_slave_link_init() - sata_lpm_ignore_phy_events() * group above functions together in * include libata-sata.c in the build when CONFIG_SATA_HOST=y Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 37582 572 40 38194 9532 drivers/ata/libata-core.o after: 36762 572 40 37374 91fe drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/Makefile | 1 + drivers/ata/libata-core.c | 245 ------------------------------------ drivers/ata/libata-sata.c | 258 ++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 16 ++- 4 files changed, 269 insertions(+), 251 deletions(-) create mode 100644 drivers/ata/libata-sata.c diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index cdaf965fed25..b8aebfb14e82 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -123,6 +123,7 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o libata-y := libata-core.o libata-scsi.o libata-eh.o \ libata-transport.o libata-trace.o +libata-$(CONFIG_SATA_HOST) += libata-sata.o libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dcdb7fb46dbd..b4a952dce7ab 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -531,81 +531,6 @@ int atapi_cmd_type(u8 opcode) } EXPORT_SYMBOL_GPL(atapi_cmd_type); -/** - * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure - * @tf: Taskfile to convert - * @pmp: Port multiplier port - * @is_cmd: This FIS is for command - * @fis: Buffer into which data will output - * - * Converts a standard ATA taskfile to a Serial ATA - * FIS structure (Register - Host to Device). - * - * LOCKING: - * Inherited from caller. - */ -void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) -{ - fis[0] = 0x27; /* Register - Host to Device FIS */ - fis[1] = pmp & 0xf; /* Port multiplier number*/ - if (is_cmd) - fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ - - fis[2] = tf->command; - fis[3] = tf->feature; - - fis[4] = tf->lbal; - fis[5] = tf->lbam; - fis[6] = tf->lbah; - fis[7] = tf->device; - - fis[8] = tf->hob_lbal; - fis[9] = tf->hob_lbam; - fis[10] = tf->hob_lbah; - fis[11] = tf->hob_feature; - - fis[12] = tf->nsect; - fis[13] = tf->hob_nsect; - fis[14] = 0; - fis[15] = tf->ctl; - - fis[16] = tf->auxiliary & 0xff; - fis[17] = (tf->auxiliary >> 8) & 0xff; - fis[18] = (tf->auxiliary >> 16) & 0xff; - fis[19] = (tf->auxiliary >> 24) & 0xff; -} -EXPORT_SYMBOL_GPL(ata_tf_to_fis); - -/** - * ata_tf_from_fis - Convert SATA FIS to ATA taskfile - * @fis: Buffer from which data will be input - * @tf: Taskfile to output - * - * Converts a serial ATA FIS structure to a standard ATA taskfile. - * - * LOCKING: - * Inherited from caller. - */ - -void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) -{ - tf->command = fis[2]; /* status */ - tf->feature = fis[3]; /* error */ - - tf->lbal = fis[4]; - tf->lbam = fis[5]; - tf->lbah = fis[6]; - tf->device = fis[7]; - - tf->hob_lbal = fis[8]; - tf->hob_lbam = fis[9]; - tf->hob_lbah = fis[10]; - - tf->nsect = fis[12]; - tf->hob_nsect = fis[13]; -} -EXPORT_SYMBOL_GPL(ata_tf_from_fis); - static const u8 ata_rw_cmds[] = { /* pio multi */ ATA_CMD_READ_MULTI, @@ -3779,81 +3704,6 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, } EXPORT_SYMBOL_GPL(sata_link_resume); -/** - * sata_link_scr_lpm - manipulate SControl IPM and SPM fields - * @link: ATA link to manipulate SControl for - * @policy: LPM policy to configure - * @spm_wakeup: initiate LPM transition to active state - * - * Manipulate the IPM field of the SControl register of @link - * according to @policy. If @policy is ATA_LPM_MAX_POWER and - * @spm_wakeup is %true, the SPM field is manipulated to wake up - * the link. This function also clears PHYRDY_CHG before - * returning. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, - bool spm_wakeup) -{ - struct ata_eh_context *ehc = &link->eh_context; - bool woken_up = false; - u32 scontrol; - int rc; - - rc = sata_scr_read(link, SCR_CONTROL, &scontrol); - if (rc) - return rc; - - switch (policy) { - case ATA_LPM_MAX_POWER: - /* disable all LPM transitions */ - scontrol |= (0x7 << 8); - /* initiate transition to active state */ - if (spm_wakeup) { - scontrol |= (0x4 << 12); - woken_up = true; - } - break; - case ATA_LPM_MED_POWER: - /* allow LPM to PARTIAL */ - scontrol &= ~(0x1 << 8); - scontrol |= (0x6 << 8); - break; - case ATA_LPM_MED_POWER_WITH_DIPM: - case ATA_LPM_MIN_POWER_WITH_PARTIAL: - case ATA_LPM_MIN_POWER: - if (ata_link_nr_enabled(link) > 0) - /* no restrictions on LPM transitions */ - scontrol &= ~(0x7 << 8); - else { - /* empty port, power off */ - scontrol &= ~0xf; - scontrol |= (0x1 << 2); - } - break; - default: - WARN_ON(1); - } - - rc = sata_scr_write(link, SCR_CONTROL, scontrol); - if (rc) - return rc; - - /* give the link time to transit out of LPM state */ - if (woken_up) - msleep(10); - - /* clear PHYRDY_CHG from SError */ - ehc->i.serror &= ~SERR_PHYRDY_CHG; - return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); -} -EXPORT_SYMBOL_GPL(sata_link_scr_lpm); - /** * ata_std_prereset - prepare for reset * @link: ATA link to be reset @@ -6118,69 +5968,6 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, } EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); -/** - * ata_slave_link_init - initialize slave link - * @ap: port to initialize slave link for - * - * Create and initialize slave link for @ap. This enables slave - * link handling on the port. - * - * In libata, a port contains links and a link contains devices. - * There is single host link but if a PMP is attached to it, - * there can be multiple fan-out links. On SATA, there's usually - * a single device connected to a link but PATA and SATA - * controllers emulating TF based interface can have two - master - * and slave. - * - * However, there are a few controllers which don't fit into this - * abstraction too well - SATA controllers which emulate TF - * interface with both master and slave devices but also have - * separate SCR register sets for each device. These controllers - * need separate links for physical link handling - * (e.g. onlineness, link speed) but should be treated like a - * traditional M/S controller for everything else (e.g. command - * issue, softreset). - * - * slave_link is libata's way of handling this class of - * controllers without impacting core layer too much. For - * anything other than physical link handling, the default host - * link is used for both master and slave. For physical link - * handling, separate @ap->slave_link is used. All dirty details - * are implemented inside libata core layer. From LLD's POV, the - * only difference is that prereset, hardreset and postreset are - * called once more for the slave link, so the reset sequence - * looks like the following. - * - * prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> - * softreset(M) -> postreset(M) -> postreset(S) - * - * Note that softreset is called only for the master. Softreset - * resets both M/S by definition, so SRST on master should handle - * both (the standard method will work just fine). - * - * LOCKING: - * Should be called before host is registered. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int ata_slave_link_init(struct ata_port *ap) -{ - struct ata_link *link; - - WARN_ON(ap->slave_link); - WARN_ON(ap->flags & ATA_FLAG_PMP); - - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) - return -ENOMEM; - - ata_link_init(ap, link, 1); - ap->slave_link = link; - return 0; -} -EXPORT_SYMBOL_GPL(ata_slave_link_init); - static void ata_host_stop(struct device *gendev, void *res) { struct ata_host *host = dev_get_drvdata(gendev); @@ -7106,38 +6893,6 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, } EXPORT_SYMBOL_GPL(ata_wait_register); -/** - * sata_lpm_ignore_phy_events - test if PHY event should be ignored - * @link: Link receiving the event - * - * Test whether the received PHY event has to be ignored or not. - * - * LOCKING: - * None: - * - * RETURNS: - * True if the event has to be ignored. - */ -bool sata_lpm_ignore_phy_events(struct ata_link *link) -{ - unsigned long lpm_timeout = link->last_lpm_change + - msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); - - /* if LPM is enabled, PHYRDY doesn't mean anything */ - if (link->lpm_policy > ATA_LPM_MAX_POWER) - return true; - - /* ignore the first PHY event after the LPM policy changed - * as it is might be spurious - */ - if ((link->flags & ATA_LFLAG_CHANGED) && - time_before(jiffies, lpm_timeout)) - return true; - - return false; -} -EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); - /* * Dummy port_ops */ diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c new file mode 100644 index 000000000000..04f1ecaf414c --- /dev/null +++ b/drivers/ata/libata-sata.c @@ -0,0 +1,258 @@ +// 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 + */ + +#include +#include +#include + +#include "libata.h" + +/** + * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure + * @tf: Taskfile to convert + * @pmp: Port multiplier port + * @is_cmd: This FIS is for command + * @fis: Buffer into which data will output + * + * Converts a standard ATA taskfile to a Serial ATA + * FIS structure (Register - Host to Device). + * + * LOCKING: + * Inherited from caller. + */ +void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) +{ + fis[0] = 0x27; /* Register - Host to Device FIS */ + fis[1] = pmp & 0xf; /* Port multiplier number*/ + if (is_cmd) + fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ + + fis[2] = tf->command; + fis[3] = tf->feature; + + fis[4] = tf->lbal; + fis[5] = tf->lbam; + fis[6] = tf->lbah; + fis[7] = tf->device; + + fis[8] = tf->hob_lbal; + fis[9] = tf->hob_lbam; + fis[10] = tf->hob_lbah; + fis[11] = tf->hob_feature; + + fis[12] = tf->nsect; + fis[13] = tf->hob_nsect; + fis[14] = 0; + fis[15] = tf->ctl; + + fis[16] = tf->auxiliary & 0xff; + fis[17] = (tf->auxiliary >> 8) & 0xff; + fis[18] = (tf->auxiliary >> 16) & 0xff; + fis[19] = (tf->auxiliary >> 24) & 0xff; +} +EXPORT_SYMBOL_GPL(ata_tf_to_fis); + +/** + * ata_tf_from_fis - Convert SATA FIS to ATA taskfile + * @fis: Buffer from which data will be input + * @tf: Taskfile to output + * + * Converts a serial ATA FIS structure to a standard ATA taskfile. + * + * LOCKING: + * Inherited from caller. + */ + +void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) +{ + tf->command = fis[2]; /* status */ + tf->feature = fis[3]; /* error */ + + tf->lbal = fis[4]; + tf->lbam = fis[5]; + tf->lbah = fis[6]; + tf->device = fis[7]; + + tf->hob_lbal = fis[8]; + tf->hob_lbam = fis[9]; + tf->hob_lbah = fis[10]; + + tf->nsect = fis[12]; + tf->hob_nsect = fis[13]; +} +EXPORT_SYMBOL_GPL(ata_tf_from_fis); + +/** + * sata_link_scr_lpm - manipulate SControl IPM and SPM fields + * @link: ATA link to manipulate SControl for + * @policy: LPM policy to configure + * @spm_wakeup: initiate LPM transition to active state + * + * Manipulate the IPM field of the SControl register of @link + * according to @policy. If @policy is ATA_LPM_MAX_POWER and + * @spm_wakeup is %true, the SPM field is manipulated to wake up + * the link. This function also clears PHYRDY_CHG before + * returning. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, + bool spm_wakeup) +{ + struct ata_eh_context *ehc = &link->eh_context; + bool woken_up = false; + u32 scontrol; + int rc; + + rc = sata_scr_read(link, SCR_CONTROL, &scontrol); + if (rc) + return rc; + + switch (policy) { + case ATA_LPM_MAX_POWER: + /* disable all LPM transitions */ + scontrol |= (0x7 << 8); + /* initiate transition to active state */ + if (spm_wakeup) { + scontrol |= (0x4 << 12); + woken_up = true; + } + break; + case ATA_LPM_MED_POWER: + /* allow LPM to PARTIAL */ + scontrol &= ~(0x1 << 8); + scontrol |= (0x6 << 8); + break; + case ATA_LPM_MED_POWER_WITH_DIPM: + case ATA_LPM_MIN_POWER_WITH_PARTIAL: + case ATA_LPM_MIN_POWER: + if (ata_link_nr_enabled(link) > 0) + /* no restrictions on LPM transitions */ + scontrol &= ~(0x7 << 8); + else { + /* empty port, power off */ + scontrol &= ~0xf; + scontrol |= (0x1 << 2); + } + break; + default: + WARN_ON(1); + } + + rc = sata_scr_write(link, SCR_CONTROL, scontrol); + if (rc) + return rc; + + /* give the link time to transit out of LPM state */ + if (woken_up) + msleep(10); + + /* clear PHYRDY_CHG from SError */ + ehc->i.serror &= ~SERR_PHYRDY_CHG; + return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); +} +EXPORT_SYMBOL_GPL(sata_link_scr_lpm); + +/** + * ata_slave_link_init - initialize slave link + * @ap: port to initialize slave link for + * + * Create and initialize slave link for @ap. This enables slave + * link handling on the port. + * + * In libata, a port contains links and a link contains devices. + * There is single host link but if a PMP is attached to it, + * there can be multiple fan-out links. On SATA, there's usually + * a single device connected to a link but PATA and SATA + * controllers emulating TF based interface can have two - master + * and slave. + * + * However, there are a few controllers which don't fit into this + * abstraction too well - SATA controllers which emulate TF + * interface with both master and slave devices but also have + * separate SCR register sets for each device. These controllers + * need separate links for physical link handling + * (e.g. onlineness, link speed) but should be treated like a + * traditional M/S controller for everything else (e.g. command + * issue, softreset). + * + * slave_link is libata's way of handling this class of + * controllers without impacting core layer too much. For + * anything other than physical link handling, the default host + * link is used for both master and slave. For physical link + * handling, separate @ap->slave_link is used. All dirty details + * are implemented inside libata core layer. From LLD's POV, the + * only difference is that prereset, hardreset and postreset are + * called once more for the slave link, so the reset sequence + * looks like the following. + * + * prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> + * softreset(M) -> postreset(M) -> postreset(S) + * + * Note that softreset is called only for the master. Softreset + * resets both M/S by definition, so SRST on master should handle + * both (the standard method will work just fine). + * + * LOCKING: + * Should be called before host is registered. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_slave_link_init(struct ata_port *ap) +{ + struct ata_link *link; + + WARN_ON(ap->slave_link); + WARN_ON(ap->flags & ATA_FLAG_PMP); + + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (!link) + return -ENOMEM; + + ata_link_init(ap, link, 1); + ap->slave_link = link; + return 0; +} +EXPORT_SYMBOL_GPL(ata_slave_link_init); + +/** + * sata_lpm_ignore_phy_events - test if PHY event should be ignored + * @link: Link receiving the event + * + * Test whether the received PHY event has to be ignored or not. + * + * LOCKING: + * None: + * + * RETURNS: + * True if the event has to be ignored. + */ +bool sata_lpm_ignore_phy_events(struct ata_link *link) +{ + unsigned long lpm_timeout = link->last_lpm_change + + msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); + + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (link->lpm_policy > ATA_LPM_MAX_POWER) + return true; + + /* ignore the first PHY event after the LPM policy changed + * as it is might be spurious + */ + if ((link->flags & ATA_LFLAG_CHANGED) && + time_before(jiffies, lpm_timeout)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); diff --git a/include/linux/libata.h b/include/linux/libata.h index 661d76038684..b419d7412f71 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1082,8 +1082,6 @@ extern int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline); extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); -extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, - bool spm_wakeup); extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); @@ -1094,7 +1092,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); @@ -1152,9 +1149,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, @@ -1195,6 +1189,16 @@ 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 + */ +extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, + bool spm_wakeup); +extern int ata_slave_link_init(struct ata_port *ap); +extern void ata_tf_to_fis(const struct ata_taskfile *tf, + u8 pmp, int is_cmd, u8 *fis); +extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); extern int ata_cable_40wire(struct ata_port *ap); From 6eab1bc0eecb541f4c383a0823902dc8f5d99861 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:12 +0100 Subject: [PATCH 26/36] ata: move sata_scr_*() to libata-sata.c * move sata_scr_*() to libata-sata.c * add static inlines for CONFIG_SATA_HOST=n case Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 35642 572 40 36254 8d9e drivers/ata/libata-core.o 16607 18 0 16625 40f1 drivers/ata/libata-eh.o after: 32846 572 40 33458 82b2 drivers/ata/libata-core.o 16243 18 0 16261 3f85 drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 109 -------------------------------------- drivers/ata/libata-sata.c | 109 ++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 24 +++++++-- 3 files changed, 129 insertions(+), 113 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b4a952dce7ab..ba1e5c4d3c09 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5215,115 +5215,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; -} -EXPORT_SYMBOL_GPL(sata_scr_valid); - -/** - * sata_scr_read - read SCR register of the specified port - * @link: ATA link to read SCR for - * @reg: SCR to read - * @val: Place to store read value - * - * Read SCR register @reg of @link into *@val. This function is - * guaranteed to succeed if @link is ap->link, the cable type of - * the port is SATA and the port implements ->scr_read. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_read(struct ata_link *link, int reg, u32 *val) -{ - if (ata_is_host_link(link)) { - if (sata_scr_valid(link)) - return link->ap->ops->scr_read(link, reg, val); - return -EOPNOTSUPP; - } - - return sata_pmp_scr_read(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_read); - -/** - * sata_scr_write - write SCR register of the specified port - * @link: ATA link to write SCR for - * @reg: SCR to write - * @val: value to write - * - * Write @val to SCR register @reg of @link. This function is - * guaranteed to succeed if @link is ap->link, the cable type of - * the port is SATA and the port implements ->scr_read. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_write(struct ata_link *link, int reg, u32 val) -{ - if (ata_is_host_link(link)) { - if (sata_scr_valid(link)) - return link->ap->ops->scr_write(link, reg, val); - return -EOPNOTSUPP; - } - - return sata_pmp_scr_write(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_write); - -/** - * sata_scr_write_flush - write SCR register of the specified port and flush - * @link: ATA link to write SCR for - * @reg: SCR to write - * @val: value to write - * - * This function is identical to sata_scr_write() except that this - * function performs flush after writing to the register. - * - * LOCKING: - * None if @link is ap->link. Kernel thread context otherwise. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) -{ - if (ata_is_host_link(link)) { - int rc; - - if (sata_scr_valid(link)) { - rc = link->ap->ops->scr_write(link, reg, val); - if (rc == 0) - rc = link->ap->ops->scr_read(link, reg, &val); - return rc; - } - return -EOPNOTSUPP; - } - - return sata_pmp_scr_write(link, reg, val); -} -EXPORT_SYMBOL_GPL(sata_scr_write_flush); - /** * ata_phys_link_online - test whether the given link is online * @link: ATA link to test diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 04f1ecaf414c..1ef4c19864ac 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -12,6 +12,115 @@ #include "libata.h" +/** + * 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 diff --git a/include/linux/libata.h b/include/linux/libata.h index b419d7412f71..86703ce5a33e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1125,10 +1125,6 @@ extern void ata_sas_tport_delete(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); -extern int sata_scr_valid(struct ata_link *link); -extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); -extern int sata_scr_write(struct ata_link *link, int reg, u32 val); -extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val); extern bool ata_link_online(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM @@ -1193,6 +1189,26 @@ extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port * /* * SATA specific code - drivers/ata/libata-sata.c */ +#ifdef CONFIG_SATA_HOST +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); +#else +static inline int sata_scr_valid(struct ata_link *link) { return 0; } +static inline int sata_scr_read(struct ata_link *link, int reg, u32 *val) +{ + return -EOPNOTSUPP; +} +static inline int sata_scr_write(struct ata_link *link, int reg, u32 val) +{ + return -EOPNOTSUPP; +} +static inline int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) +{ + return -EOPNOTSUPP; +} +#endif extern int 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); From ab4117cf2470618ffd5af16fa7c363b81260d6e7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:13 +0100 Subject: [PATCH 27/36] ata: move *sata_set_spd*() to libata-sata.c * move *sata_set_spd*() to libata-sata.c * add static inlines for CONFIG_SATA_HOST=n case Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32842 572 40 33458 82ae drivers/ata/libata-core.o after: 32812 572 40 33428 8290 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 81 --------------------------------------- drivers/ata/libata-sata.c | 81 +++++++++++++++++++++++++++++++++++++++ drivers/ata/libata.h | 7 ++++ include/linux/libata.h | 3 +- 4 files changed, 90 insertions(+), 82 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ba1e5c4d3c09..13214ebd0e5c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3050,87 +3050,6 @@ 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; -} -EXPORT_SYMBOL_GPL(sata_set_spd); - #ifdef CONFIG_ATA_ACPI /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 1ef4c19864ac..d66afdc33d54 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -271,6 +271,87 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, } 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. + */ +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); + /** * ata_slave_link_init - initialize slave link * @ap: port to initialize slave link for diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index cd8090ad43e5..53b45ebe3d55 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -87,6 +87,13 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, #define to_ata_port(d) container_of(d, struct ata_port, tdev) +/* libata-sata.c */ +#ifdef CONFIG_SATA_HOST +int sata_set_spd_needed(struct ata_link *link); +#else +static inline int sata_set_spd_needed(struct ata_link *link) { return 1; } +#endif + /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; diff --git a/include/linux/libata.h b/include/linux/libata.h index 86703ce5a33e..f0817a8f1e3f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1074,7 +1074,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) return ap->ops == &ata_dummy_port_ops; } -extern int sata_set_spd(struct ata_link *link); extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); @@ -1194,6 +1193,7 @@ 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); #else 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) @@ -1208,6 +1208,7 @@ 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; } #endif extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup); From 9d3158f5cb11142d85c351fa0e0087ef95ac9cb8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:14 +0100 Subject: [PATCH 28/36] ata: move sata_link_{debounce,resume}() to libata-sata.c * move sata_link_{debounce,resume}() to libata-sata.c * add static inline for CONFIG_SATA_HOST=n case (only one, for sata_link_resume() is needed) Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32816 572 40 33428 8294 drivers/ata/libata-core.o after: 32724 572 40 33336 8238 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 138 -------------------------------------- drivers/ata/libata-sata.c | 138 ++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 14 ++-- 3 files changed, 148 insertions(+), 142 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 13214ebd0e5c..4ca81ef7c8bd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3485,144 +3485,6 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, } EXPORT_SYMBOL_GPL(ata_wait_after_reset); -/** - * sata_link_debounce - debounce SATA phy status - * @link: ATA link to debounce SATA phy status for - * @params: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * - * Make sure SStatus of @link reaches stable state, determined by - * holding the same value where DET is not 1 for @duration polled - * every @interval, before @timeout. Timeout constraints the - * beginning of the stable state. Because DET gets stuck at 1 on - * some controllers after hot unplugging, this functions waits - * until timeout then returns 0 if DET is stable at 1. - * - * @timeout is further limited by @deadline. The sooner of the - * two is used. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_link_debounce(struct ata_link *link, const unsigned long *params, - unsigned long deadline) -{ - unsigned long interval = params[0]; - unsigned long duration = params[1]; - unsigned long last_jiffies, t; - u32 last, cur; - int rc; - - t = ata_deadline(jiffies, params[2]); - if (time_before(t, deadline)) - deadline = t; - - if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - last = cur; - last_jiffies = jiffies; - - while (1) { - ata_msleep(link->ap, interval); - if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - /* DET stable? */ - if (cur == last) { - if (cur == 1 && time_before(jiffies, deadline)) - continue; - if (time_after(jiffies, - ata_deadline(last_jiffies, duration))) - return 0; - continue; - } - - /* unstable, start over */ - last = cur; - last_jiffies = jiffies; - - /* Check deadline. If debouncing failed, return - * -EPIPE to tell upper layer to lower link speed. - */ - if (time_after(jiffies, deadline)) - return -EPIPE; - } -} -EXPORT_SYMBOL_GPL(sata_link_debounce); - -/** - * sata_link_resume - resume SATA link - * @link: ATA link to resume SATA - * @params: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * - * Resume SATA phy @link and debounce it. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_link_resume(struct ata_link *link, const unsigned long *params, - unsigned long deadline) -{ - int tries = ATA_LINK_RESUME_TRIES; - u32 scontrol, serror; - int rc; - - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - return rc; - - /* - * Writes to SControl sometimes get ignored under certain - * controllers (ata_piix SIDPR). Make sure DET actually is - * cleared. - */ - do { - scontrol = (scontrol & 0x0f0) | 0x300; - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - return rc; - /* - * Some PHYs react badly if SStatus is pounded - * immediately after resuming. Delay 200ms before - * debouncing. - */ - if (!(link->flags & ATA_LFLAG_NO_DB_DELAY)) - ata_msleep(link->ap, 200); - - /* is SControl restored correctly? */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - return rc; - } while ((scontrol & 0xf0f) != 0x300 && --tries); - - if ((scontrol & 0xf0f) != 0x300) { - ata_link_warn(link, "failed to resume link (SControl %X)\n", - scontrol); - return 0; - } - - if (tries < ATA_LINK_RESUME_TRIES) - ata_link_warn(link, "link resume succeeded after %d retries\n", - ATA_LINK_RESUME_TRIES - tries); - - if ((rc = sata_link_debounce(link, params, deadline))) - return rc; - - /* clear SError, some PHYs require this even for SRST to work */ - if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) - rc = sata_scr_write(link, SCR_ERROR, serror); - - return rc != -EINVAL ? rc : 0; -} -EXPORT_SYMBOL_GPL(sata_link_resume); - /** * ata_std_prereset - prepare for reset * @link: ATA link to be reset diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index d66afdc33d54..34852fced999 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -196,6 +196,144 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) } 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 diff --git a/include/linux/libata.h b/include/linux/libata.h index f0817a8f1e3f..b05538d06919 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1077,10 +1077,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); -extern int sata_link_debounce(struct ata_link *link, - const unsigned long *params, unsigned long deadline); -extern int sata_link_resume(struct ata_link *link, const unsigned long *params, - unsigned long deadline); extern int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, unsigned long deadline, bool *online, int (*check_ready)(struct ata_link *)); @@ -1194,6 +1190,8 @@ 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_resume(struct ata_link *link, const unsigned long *params, + unsigned long deadline); #else 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) @@ -1209,7 +1207,15 @@ 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_resume(struct ata_link *link, + const unsigned long *params, + unsigned long deadline) +{ + return -EOPNOTSUPP; +} #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); From 78c97c80d76b0590fc6ff5e20f4b18f105aa4fae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:15 +0100 Subject: [PATCH 29/36] ata: move sata_link_hardreset() to libata-sata.c * move sata_link_hardreset() to libata-sata.c * add static inline for CONFIG_SATA_HOST=n case * make sata_set_spd_needed() static Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32724 572 40 33336 8238 drivers/ata/libata-core.o after: 32559 572 40 33171 8193 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 113 ------------------------------------- drivers/ata/libata-sata.c | 115 +++++++++++++++++++++++++++++++++++++- drivers/ata/libata.h | 7 --- include/linux/libata.h | 16 +++++- 4 files changed, 127 insertions(+), 124 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4ca81ef7c8bd..19624d056d92 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3531,119 +3531,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) } EXPORT_SYMBOL_GPL(ata_std_prereset); -/** - * sata_link_hardreset - reset link via SATA phy reset - * @link: link to reset - * @timing: timing parameters { interval, duration, timeout } in msec - * @deadline: deadline jiffies for the operation - * @online: optional out parameter indicating link onlineness - * @check_ready: optional callback to check link readiness - * - * SATA phy-reset @link using DET bits of SControl register. - * After hardreset, link readiness is waited upon using - * ata_wait_ready() if @check_ready is specified. LLDs are - * allowed to not specify @check_ready and wait itself after this - * function returns. Device classification is LLD's - * responsibility. - * - * *@online is set to one iff reset succeeded and @link is online - * after reset. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, - unsigned long deadline, - bool *online, int (*check_ready)(struct ata_link *)) -{ - u32 scontrol; - int rc; - - DPRINTK("ENTER\n"); - - if (online) - *online = false; - - if (sata_set_spd_needed(link)) { - /* SATA spec says nothing about how to reconfigure - * spd. To be on the safe side, turn off phy during - * reconfiguration. This works for at least ICH7 AHCI - * and Sil3124. - */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - goto out; - - scontrol = (scontrol & 0x0f0) | 0x304; - - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - goto out; - - sata_set_spd(link); - } - - /* issue phy wake/reset */ - if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) - goto out; - - scontrol = (scontrol & 0x0f0) | 0x301; - - if ((rc = sata_scr_write_flush(link, SCR_CONTROL, scontrol))) - goto out; - - /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 - * 10.4.2 says at least 1 ms. - */ - ata_msleep(link->ap, 1); - - /* bring link back */ - rc = sata_link_resume(link, timing, deadline); - if (rc) - goto out; - /* if link is offline nothing more to do */ - if (ata_phys_link_offline(link)) - goto out; - - /* Link is online. From this point, -ENODEV too is an error. */ - if (online) - *online = true; - - if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) { - /* If PMP is supported, we have to do follow-up SRST. - * Some PMPs don't send D2H Reg FIS after hardreset if - * the first port is empty. Wait only for - * ATA_TMOUT_PMP_SRST_WAIT. - */ - if (check_ready) { - unsigned long pmp_deadline; - - pmp_deadline = ata_deadline(jiffies, - ATA_TMOUT_PMP_SRST_WAIT); - if (time_after(pmp_deadline, deadline)) - pmp_deadline = deadline; - ata_wait_ready(link, pmp_deadline, check_ready); - } - rc = -EAGAIN; - goto out; - } - - rc = 0; - if (check_ready) - rc = ata_wait_ready(link, deadline, check_ready); - out: - if (rc && rc != -EAGAIN) { - /* online is set iff link is online && reset succeeded */ - if (online) - *online = false; - ata_link_err(link, "COMRESET failed (errno=%d)\n", rc); - } - DPRINTK("EXIT, rc=%d\n", rc); - return rc; -} -EXPORT_SYMBOL_GPL(sata_link_hardreset); - /** * sata_std_hardreset - COMRESET w/o waiting or classification * @link: link to reset diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 34852fced999..05a1872ba329 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -449,7 +449,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) * RETURNS: * 1 if SATA spd configuration is needed, 0 otherwise. */ -int sata_set_spd_needed(struct ata_link *link) +static int sata_set_spd_needed(struct ata_link *link) { u32 scontrol; @@ -490,6 +490,119 @@ int sata_set_spd(struct ata_link *link) } 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_slave_link_init - initialize slave link * @ap: port to initialize slave link for diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 53b45ebe3d55..cd8090ad43e5 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -87,13 +87,6 @@ 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 sata_set_spd_needed(struct ata_link *link); -#else -static inline int sata_set_spd_needed(struct ata_link *link) { return 1; } -#endif - /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; diff --git a/include/linux/libata.h b/include/linux/libata.h index b05538d06919..981f73c02509 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1077,9 +1077,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap) extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)); -extern int sata_link_hardreset(struct ata_link *link, - const unsigned long *timing, unsigned long deadline, - bool *online, int (*check_ready)(struct ata_link *)); extern int sata_std_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); @@ -1190,6 +1187,9 @@ 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); #else @@ -1207,6 +1207,16 @@ 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) From 61a11986d33d01dbef745d49c0536961eb06d2f1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:16 +0100 Subject: [PATCH 30/36] ata: move ata_qc_complete_multiple() to libata-sata.c * move ata_qc_complete_multiple() to libata-sata.c Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32559 572 40 33171 8193 drivers/ata/libata-core.o after: 32162 572 40 32774 8006 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 59 --------------------------------------- drivers/ata/libata-sata.c | 59 +++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 2 +- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 19624d056d92..2ef0960b2154 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4749,65 +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; -} -EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); - /** * ata_qc_issue - issue taskfile to device * @qc: command to issue to device diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 05a1872ba329..849582e0d653 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -603,6 +603,65 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, } EXPORT_SYMBOL_GPL(sata_link_hardreset); +/** + * ata_qc_complete_multiple - Complete multiple qcs successfully + * @ap: port in question + * @qc_active: new qc_active mask + * + * Complete in-flight commands. This functions is meant to be + * called from low-level driver's interrupt routine to complete + * requests normally. ap->qc_active and @qc_active is compared + * and commands are completed accordingly. + * + * Always use this function when completing multiple NCQ commands + * from IRQ handlers instead of calling ata_qc_complete() + * multiple times to keep IRQ expect status properly in sync. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * Number of completed commands on success, -errno otherwise. + */ +int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active) +{ + u64 done_mask, ap_qc_active = ap->qc_active; + int nr_done = 0; + + /* + * If the internal tag is set on ap->qc_active, then we care about + * bit0 on the passed in qc_active mask. Move that bit up to match + * the internal tag. + */ + if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) { + qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL; + qc_active ^= qc_active & 0x01; + } + + done_mask = ap_qc_active ^ qc_active; + + if (unlikely(done_mask & qc_active)) { + ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n", + ap->qc_active, qc_active); + return -EINVAL; + } + + while (done_mask) { + struct ata_queued_cmd *qc; + unsigned int tag = __ffs64(done_mask); + + qc = ata_qc_from_tag(ap, tag); + if (qc) { + ata_qc_complete(qc); + nr_done++; + } + done_mask &= ~(1ULL << tag); + } + + return nr_done; +} +EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); + /** * ata_slave_link_init - initialize slave link * @ap: port to initialize slave link for diff --git a/include/linux/libata.h b/include/linux/libata.h index 981f73c02509..08fec96a6a1e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1160,7 +1160,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, @@ -1232,6 +1231,7 @@ extern int ata_slave_link_init(struct ata_port *ap); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); +extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); extern bool sata_lpm_ignore_phy_events(struct ata_link *link); extern int ata_cable_40wire(struct ata_port *ap); From 2b384ede7107a528c65ec826e045b572bcb2aa0b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:17 +0100 Subject: [PATCH 31/36] ata: move sata_deb_timing_*() to libata-sata.c * move sata_deb_timing_*() to libata-sata.c * add static inline for sata_ehc_deb_timing() for CONFIG_SATA_HOST=n case Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32158 572 40 32770 8002 drivers/ata/libata-core.o after: 32015 572 40 32627 7f73 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 8 -------- drivers/ata/libata-sata.c | 8 ++++++++ include/linux/libata.h | 31 ++++++++++++++++++------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2ef0960b2154..20c22dbc1f24 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -65,14 +65,6 @@ #include "libata.h" #include "libata-transport.h" -/* debounce timing parameters in msecs { interval, duration, timeout } */ -const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_normal); -const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); -const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; -EXPORT_SYMBOL_GPL(sata_deb_timing_long); - const struct ata_port_operations ata_base_port_ops = { .prereset = ata_std_prereset, .postreset = ata_std_postreset, diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 849582e0d653..f3ad4aca5d09 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -12,6 +12,14 @@ #include "libata.h" +/* debounce timing parameters in msecs { interval, duration, timeout } */ +const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_normal); +const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); +const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; +EXPORT_SYMBOL_GPL(sata_deb_timing_long); + /** * sata_scr_valid - test whether SCRs are accessible * @link: ATA link to test SCR accessibility for diff --git a/include/linux/libata.h b/include/linux/libata.h index 08fec96a6a1e..90c929b5df3d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1019,10 +1019,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; @@ -1060,15 +1056,6 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf) (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); } -static inline const unsigned long * -sata_ehc_deb_timing(struct ata_eh_context *ehc) -{ - if (ehc->i.flags & ATA_EHI_HOTPLUGGED) - return sata_deb_timing_hotplug; - else - return sata_deb_timing_normal; -} - static inline int ata_port_is_dummy(struct ata_port *ap) { return ap->ops == &ata_dummy_port_ops; @@ -1181,6 +1168,19 @@ extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port * * 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); @@ -1192,6 +1192,11 @@ extern int sata_link_hardreset(struct ata_link *link, extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); #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) { From ec811a94c5bb6916d01c02dc99c8cecfa59cbb85 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:18 +0100 Subject: [PATCH 32/36] ata: start separating SATA specific code from libata-scsi.c Start separating SATA specific code from libata-scsi.c: * un-static ata_scsi_find_dev() * move following code to libata-sata.c: - SATA only sysfs device attributes handling - __ata_change_queue_depth() - ata_scsi_change_queue_depth() * cover with CONFIG_SATA_HOST ifdef SATA only sysfs device attributes handling code and ATA_SHT_NCQ() macro in Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 20702 105 576 21383 5387 drivers/ata/libata-scsi.o after: 19137 23 576 19736 4d18 drivers/ata/libata-scsi.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-sata.c | 298 +++++++++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 301 +------------------------------------- drivers/ata/libata.h | 2 + include/linux/libata.h | 9 +- 4 files changed, 308 insertions(+), 302 deletions(-) diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index f3ad4aca5d09..341699f5af20 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "libata.h" @@ -764,3 +765,300 @@ bool sata_lpm_ignore_phy_events(struct ata_link *link) 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); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ae63ef7adcb9..a5dfcd9e09a1 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -46,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 @@ -87,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) { @@ -255,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) { @@ -380,100 +236,12 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, field, 0xff, 0); } -static ssize_t -ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_store(ap, buf, count); - return -EINVAL; -} - -static ssize_t -ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) - return ap->ops->em_show(ap, buf); - return -EINVAL; -} -DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, - ata_scsi_em_message_show, ata_scsi_em_message_store); -EXPORT_SYMBOL_GPL(dev_attr_em_message); - -static ssize_t -ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ata_port *ap = ata_shost_to_port(shost); - - return snprintf(buf, 23, "%d\n", ap->em_message_type); -} -DEVICE_ATTR(em_message_type, S_IRUGO, - ata_scsi_em_message_type_show, NULL); -EXPORT_SYMBOL_GPL(dev_attr_em_message_type); - -static ssize_t -ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - - if (atadev && ap->ops->sw_activity_show && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) - return ap->ops->sw_activity_show(atadev, buf); - return -EINVAL; -} - -static ssize_t -ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); - enum sw_activity val; - int rc; - - if (atadev && ap->ops->sw_activity_store && - (ap->flags & ATA_FLAG_SW_ACTIVITY)) { - val = simple_strtoul(buf, NULL, 0); - switch (val) { - case OFF: case BLINK_ON: case BLINK_OFF: - rc = ap->ops->sw_activity_store(atadev, val); - if (!rc) - return count; - else - return rc; - } - } - return -EINVAL; -} -DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, - ata_scsi_activity_store); -EXPORT_SYMBOL_GPL(dev_attr_sw_activity); - struct device_attribute *ata_common_sdev_attrs[] = { &dev_attr_unload_heads, NULL }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -struct device_attribute *ata_ncq_sdev_attrs[] = { - &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, - NULL -}; -EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); - /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined @@ -1391,73 +1159,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) } EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); -/** - * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth - * @ap: ATA port to which the device change the queue depth - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * libsas and libata have different approaches for associating a sdev to - * its ata_port. - * - */ -int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth) -{ - struct ata_device *dev; - unsigned long flags; - - if (queue_depth < 1 || queue_depth == sdev->queue_depth) - return sdev->queue_depth; - - dev = ata_scsi_find_dev(ap, sdev); - if (!dev || !ata_dev_enabled(dev)) - return sdev->queue_depth; - - /* NCQ enabled? */ - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - if (queue_depth == 1 || !ata_ncq_enabled(dev)) { - dev->flags |= ATA_DFLAG_NCQ_OFF; - queue_depth = 1; - } - spin_unlock_irqrestore(ap->lock, flags); - - /* limit and apply queue depth */ - queue_depth = min(queue_depth, sdev->host->can_queue); - queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); - queue_depth = min(queue_depth, ATA_MAX_QUEUE); - - if (sdev->queue_depth == queue_depth) - return -EINVAL; - - return scsi_change_queue_depth(sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(__ata_change_queue_depth); - -/** - * ata_scsi_change_queue_depth - SCSI callback for queue depth config - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth - * - * This is libata standard hostt->change_queue_depth callback. - * SCSI will call into this callback when user tries to set queue - * depth via sysfs. - * - * LOCKING: - * SCSI layer (we don't care) - * - * RETURNS: - * Newly configured queue depth. - */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) -{ - struct ata_port *ap = ata_shost_to_port(sdev->host); - - return __ata_change_queue_depth(ap, sdev, queue_depth); -} -EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); - /** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * @qc: Storage for translated ATA taskfile @@ -3094,7 +2795,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, * RETURNS: * Associated ATA device, or %NULL if not found. */ -static struct ata_device * +struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) { struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index cd8090ad43e5..ce3f3c039572 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -112,6 +112,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} #endif /* libata-scsi.c */ +extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap, + const struct scsi_device *scsidev); extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); diff --git a/include/linux/libata.h b/include/linux/libata.h index 90c929b5df3d..ae74fd048a32 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -530,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, @@ -1371,7 +1373,6 @@ extern int ata_link_nr_enabled(struct ata_link *link); extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; extern struct device_attribute *ata_common_sdev_attrs[]; -extern struct device_attribute *ata_ncq_sdev_attrs[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1399,10 +1400,14 @@ extern struct device_attribute *ata_ncq_sdev_attrs[]; __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), \ .sdev_attrs = ata_ncq_sdev_attrs, \ .change_queue_depth = ata_scsi_change_queue_depth +#endif /* * PMP helpers From 15964ff72832ee489ae9e31c4e1a924e80e05dcb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:19 +0100 Subject: [PATCH 33/36] ata: move ata_sas_*() to libata-sata.c * un-inline: - ata_scsi_dump_cdb() - __ata_scsi_queuecmd() * un-static: - ata_scsi_sdev_config() - ata_scsi_dev_config() - ata_scsi_dump_cdb() - __ata_scsi_queuecmd() * move ata_sas_*() to libata-sata.c: * add static inlines for CONFIG_SATA_HOST=n case for ata_sas_{allocate,free}_tag() Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 19137 23 576 19736 4d18 drivers/ata/libata-scsi.o after: 18330 23 576 18929 49f1 drivers/ata/libata-scsi.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-sata.c | 213 ++++++++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 222 +------------------------------------- drivers/ata/libata.h | 19 +++- include/linux/libata.h | 24 ++--- 4 files changed, 245 insertions(+), 233 deletions(-) diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 341699f5af20..2d934ccfc930 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -8,10 +8,12 @@ #include #include +#include #include #include #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 }; @@ -1062,3 +1064,214 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) return __ata_change_queue_depth(ap, sdev, queue_depth); } EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); + +/** + * port_alloc - Allocate port for a SAS attached SATA device + * @host: ATA host container for all SAS ports + * @port_info: Information from low-level host driver + * @shost: SCSI host that the scsi device is attached to + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * ata_port pointer on success / NULL on failure. + */ + +struct ata_port *ata_sas_port_alloc(struct ata_host *host, + struct ata_port_info *port_info, + struct Scsi_Host *shost) +{ + struct ata_port *ap; + + ap = ata_port_alloc(host); + if (!ap) + return NULL; + + ap->port_no = 0; + ap->lock = &host->lock; + ap->pio_mask = port_info->pio_mask; + ap->mwdma_mask = port_info->mwdma_mask; + ap->udma_mask = port_info->udma_mask; + ap->flags |= port_info->flags; + ap->ops = port_info->port_ops; + ap->cbl = ATA_CBL_SATA; + + return ap; +} +EXPORT_SYMBOL_GPL(ata_sas_port_alloc); + +/** + * ata_sas_port_start - Set port up for dma. + * @ap: Port to initialize + * + * Called just after data structures for each port are + * initialized. + * + * May be used as the port_start() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +int ata_sas_port_start(struct ata_port *ap) +{ + /* + * the port is marked as frozen at allocation time, but if we don't + * have new eh, we won't thaw it + */ + if (!ap->ops->error_handler) + ap->pflags &= ~ATA_PFLAG_FROZEN; + return 0; +} +EXPORT_SYMBOL_GPL(ata_sas_port_start); + +/** + * ata_port_stop - Undo ata_sas_port_start() + * @ap: Port to shut down + * + * May be used as the port_stop() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ + +void ata_sas_port_stop(struct ata_port *ap) +{ +} +EXPORT_SYMBOL_GPL(ata_sas_port_stop); + +/** + * ata_sas_async_probe - simply schedule probing and return + * @ap: Port to probe + * + * For batch scheduling of probe for sas attached ata devices, assumes + * the port has already been through ata_sas_port_init() + */ +void ata_sas_async_probe(struct ata_port *ap) +{ + __ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_async_probe); + +int ata_sas_sync_probe(struct ata_port *ap) +{ + return ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_sync_probe); + + +/** + * ata_sas_port_init - Initialize a SATA device + * @ap: SATA port to initialize + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * Zero on success, non-zero on error. + */ + +int ata_sas_port_init(struct ata_port *ap) +{ + int rc = ap->ops->port_start(ap); + + if (rc) + return rc; + ap->print_id = atomic_inc_return(&ata_print_id); + return 0; +} +EXPORT_SYMBOL_GPL(ata_sas_port_init); + +int ata_sas_tport_add(struct device *parent, struct ata_port *ap) +{ + return ata_tport_add(parent, ap); +} +EXPORT_SYMBOL_GPL(ata_sas_tport_add); + +void ata_sas_tport_delete(struct ata_port *ap) +{ + ata_tport_delete(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_tport_delete); + +/** + * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc + * @ap: SATA port to destroy + * + */ + +void ata_sas_port_destroy(struct ata_port *ap) +{ + if (ap->ops->port_stop) + ap->ops->port_stop(ap); + kfree(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_port_destroy); + +/** + * ata_sas_slave_configure - Default slave_config routine for libata devices + * @sdev: SCSI device to configure + * @ap: ATA port to which SCSI device is attached + * + * RETURNS: + * Zero. + */ + +int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap) +{ + ata_scsi_sdev_config(sdev); + ata_scsi_dev_config(sdev, ap->link.device); + return 0; +} +EXPORT_SYMBOL_GPL(ata_sas_slave_configure); + +/** + * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device + * @cmd: SCSI command to be sent + * @ap: ATA port to which the command is being sent + * + * RETURNS: + * Return value from __ata_scsi_queuecmd() if @cmd can be queued, + * 0 otherwise. + */ + +int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) +{ + int rc = 0; + + ata_scsi_dump_cdb(ap, cmd); + + if (likely(ata_dev_enabled(ap->link.device))) + rc = __ata_scsi_queuecmd(cmd, ap->link.device); + else { + cmd->result = (DID_BAD_TARGET << 16); + cmd->scsi_done(cmd); + } + return rc; +} +EXPORT_SYMBOL_GPL(ata_sas_queuecmd); + +int ata_sas_allocate_tag(struct ata_port *ap) +{ + unsigned int max_queue = ap->host->n_tags; + unsigned int i, tag; + + for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { + tag = tag < max_queue ? tag : 0; + + /* the last tag is reserved for internal command. */ + if (ata_tag_internal(tag)) + continue; + + if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { + ap->sas_last_tag = tag; + return tag; + } + } + return -1; +} + +void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) +{ + clear_bit(tag, &ap->sas_tag_allocated); +} diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a5dfcd9e09a1..36e588d88b95 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -988,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; @@ -1028,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; @@ -4005,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; @@ -4018,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; @@ -4662,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); -} diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index ce3f3c039572..6c808cf39135 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -87,6 +87,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; @@ -130,9 +142,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); diff --git a/include/linux/libata.h b/include/linux/libata.h index ae74fd048a32..da899f18a3e9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1094,18 +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 bool ata_link_online(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM @@ -1235,6 +1223,18 @@ extern int sata_link_debounce(struct ata_link *link, extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup); extern int ata_slave_link_init(struct ata_port *ap); +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); From a695de27fca5cefce0d1d93bab681e35605fee55 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:20 +0100 Subject: [PATCH 34/36] ata: start separating SATA specific code from libata-eh.c Start separating SATA specific code from libata-eh.c: * move sata_async_notification() to libata-sata.c: Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 16243 18 0 16261 3f85 drivers/ata/libata-eh.o after: 16164 18 0 16182 3f36 drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-eh.c | 74 -------------------------------------- drivers/ata/libata-sata.c | 75 +++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 2 +- 3 files changed, 76 insertions(+), 75 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8dc33b6832f0..ef4d606cd8c6 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1092,80 +1092,6 @@ int ata_port_freeze(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_port_freeze); -/** - * sata_async_notification - SATA async notification handler - * @ap: ATA port where async notification is received - * - * Handler to be called when async notification via SDB FIS is - * received. This function schedules EH if necessary. - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * 1 if EH is scheduled, 0 otherwise. - */ -int sata_async_notification(struct ata_port *ap) -{ - u32 sntf; - int rc; - - if (!(ap->flags & ATA_FLAG_AN)) - return 0; - - rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf); - if (rc == 0) - sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); - - if (!sata_pmp_attached(ap) || rc) { - /* PMP is not attached or SNTF is not available */ - if (!sata_pmp_attached(ap)) { - /* PMP is not attached. Check whether ATAPI - * AN is configured. If so, notify media - * change. - */ - struct ata_device *dev = ap->link.device; - - if ((dev->class == ATA_DEV_ATAPI) && - (dev->flags & ATA_DFLAG_AN)) - ata_scsi_media_change_notify(dev); - return 0; - } else { - /* PMP is attached but SNTF is not available. - * ATAPI async media change notification is - * not used. The PMP must be reporting PHY - * status change, schedule EH. - */ - ata_port_schedule_eh(ap); - return 1; - } - } else { - /* PMP is attached and SNTF is available */ - struct ata_link *link; - - /* check and notify ATAPI AN */ - ata_for_each_link(link, ap, EDGE) { - if (!(sntf & (1 << link->pmp))) - continue; - - if ((link->device->class == ATA_DEV_ATAPI) && - (link->device->flags & ATA_DFLAG_AN)) - ata_scsi_media_change_notify(link->device); - } - - /* If PMP is reporting that PHY status of some - * downstream ports has changed, schedule EH. - */ - if (sntf & (1 << SATA_PMP_CTRL_PORT)) { - ata_port_schedule_eh(ap); - return 1; - } - - return 0; - } -} -EXPORT_SYMBOL_GPL(sata_async_notification); - /** * ata_eh_freeze_port - EH helper to freeze port * @ap: ATA port to freeze diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 2d934ccfc930..008468e516cd 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -4,6 +4,7 @@ * * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik + * Copyright 2006 Tejun Heo */ #include @@ -1275,3 +1276,77 @@ 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); diff --git a/include/linux/libata.h b/include/linux/libata.h index da899f18a3e9..9c7ca659dc94 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1240,6 +1240,7 @@ extern void ata_tf_to_fis(const struct ata_taskfile *tf, 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); @@ -1332,7 +1333,6 @@ extern void ata_port_wait_eh(struct ata_port *ap); extern int ata_link_abort(struct ata_link *link); extern int ata_port_abort(struct ata_port *ap); extern int ata_port_freeze(struct ata_port *ap); -extern int sata_async_notification(struct ata_port *ap); extern void ata_eh_freeze_port(struct ata_port *ap); extern void ata_eh_thaw_port(struct ata_port *ap); From a0ccd2511b6f70394b30f8290da8bfc723d6bc07 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:21 +0100 Subject: [PATCH 35/36] ata: move ata_eh_analyze_ncq_error() & co. to libata-sata.c * move ata_eh_analyze_ncq_error() and ata_eh_read_log_10h() to libata-sata.c * add static inline for ata_eh_analyze_ncq_error() for CONFIG_SATA_HOST=n case (link->sactive is non-zero only if NCQ commands are actually queued so empty function body is sufficient) Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 16164 18 0 16182 3f36 drivers/ata/libata-eh.o after: 15446 18 0 15464 3c68 drivers/ata/libata-eh.o Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/libata-eh.c | 131 -------------------------------------- drivers/ata/libata-sata.c | 131 ++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 3 +- 3 files changed, 133 insertions(+), 132 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index ef4d606cd8c6..474c6c34fe02 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1351,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask) return "unknown error"; } -/** - * ata_eh_read_log_10h - Read log page 10h for NCQ error details - * @dev: Device to read log page 10h from - * @tag: Resulting tag of the failed command - * @tf: Resulting taskfile registers of the failed command - * - * Read log page 10h to obtain NCQ error details and clear error - * condition. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int ata_eh_read_log_10h(struct ata_device *dev, - int *tag, struct ata_taskfile *tf) -{ - u8 *buf = dev->link->ap->sector_buf; - unsigned int err_mask; - u8 csum; - int i; - - err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); - if (err_mask) - return -EIO; - - csum = 0; - for (i = 0; i < ATA_SECT_SIZE; i++) - csum += buf[i]; - if (csum) - ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", - csum); - - if (buf[0] & 0x80) - return -ENOENT; - - *tag = buf[0] & 0x1f; - - tf->command = buf[2]; - tf->feature = buf[3]; - tf->lbal = buf[4]; - tf->lbam = buf[5]; - tf->lbah = buf[6]; - tf->device = buf[7]; - tf->hob_lbal = buf[8]; - tf->hob_lbam = buf[9]; - tf->hob_lbah = buf[10]; - tf->nsect = buf[12]; - tf->hob_nsect = buf[13]; - if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) - tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; - - return 0; -} - /** * atapi_eh_tur - perform ATAPI TEST_UNIT_READY * @dev: target ATAPI device @@ -1590,81 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link) ehc->i.action |= action; } -/** - * ata_eh_analyze_ncq_error - analyze NCQ error - * @link: ATA link to analyze NCQ error for - * - * Read log page 10h, determine the offending qc and acquire - * error status TF. For NCQ device errors, all LLDDs have to do - * is setting AC_ERR_DEV in ehi->err_mask. This function takes - * care of the rest. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_eh_analyze_ncq_error(struct ata_link *link) -{ - struct ata_port *ap = link->ap; - struct ata_eh_context *ehc = &link->eh_context; - struct ata_device *dev = link->device; - struct ata_queued_cmd *qc; - struct ata_taskfile tf; - int tag, rc; - - /* if frozen, we can't do much */ - if (ap->pflags & ATA_PFLAG_FROZEN) - return; - - /* is it NCQ device error? */ - if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) - return; - - /* has LLDD analyzed already? */ - ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - - if (qc->err_mask) - return; - } - - /* okay, this error is ours */ - memset(&tf, 0, sizeof(tf)); - rc = ata_eh_read_log_10h(dev, &tag, &tf); - if (rc) { - ata_link_err(link, "failed to read log page 10h (errno=%d)\n", - rc); - return; - } - - if (!(link->sactive & (1 << tag))) { - ata_link_err(link, "log page 10h reported inactive tag %d\n", - tag); - return; - } - - /* we've got the perpetrator, condemn it */ - qc = __ata_qc_from_tag(ap, tag); - memcpy(&qc->result_tf, &tf, sizeof(tf)); - qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; - if (dev->class == ATA_DEV_ZAC && - ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { - char sense_key, asc, ascq; - - sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; - asc = (qc->result_tf.auxiliary >> 8) & 0xff; - ascq = qc->result_tf.auxiliary & 0xff; - ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); - ata_scsi_set_sense_information(dev, qc->scsicmd, - &qc->result_tf); - qc->flags |= ATA_QCFLAG_SENSE_VALID; - } - - ehc->i.err_mask &= ~AC_ERR_DEV; -} -EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); - /** * ata_eh_analyze_tf - analyze taskfile of a failed qc * @qc: qc to analyze diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 008468e516cd..c16423e44525 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -1350,3 +1350,134 @@ int sata_async_notification(struct ata_port *ap) } } EXPORT_SYMBOL_GPL(sata_async_notification); + +/** + * ata_eh_read_log_10h - Read log page 10h for NCQ error details + * @dev: Device to read log page 10h from + * @tag: Resulting tag of the failed command + * @tf: Resulting taskfile registers of the failed command + * + * Read log page 10h to obtain NCQ error details and clear error + * condition. + * + * LOCKING: + * Kernel thread context (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +static int ata_eh_read_log_10h(struct ata_device *dev, + int *tag, struct ata_taskfile *tf) +{ + u8 *buf = dev->link->ap->sector_buf; + unsigned int err_mask; + u8 csum; + int i; + + err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); + if (err_mask) + return -EIO; + + csum = 0; + for (i = 0; i < ATA_SECT_SIZE; i++) + csum += buf[i]; + if (csum) + ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", + csum); + + if (buf[0] & 0x80) + return -ENOENT; + + *tag = buf[0] & 0x1f; + + tf->command = buf[2]; + tf->feature = buf[3]; + tf->lbal = buf[4]; + tf->lbam = buf[5]; + tf->lbah = buf[6]; + tf->device = buf[7]; + tf->hob_lbal = buf[8]; + tf->hob_lbam = buf[9]; + tf->hob_lbah = buf[10]; + tf->nsect = buf[12]; + tf->hob_nsect = buf[13]; + if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; + + return 0; +} + +/** + * ata_eh_analyze_ncq_error - analyze NCQ error + * @link: ATA link to analyze NCQ error for + * + * Read log page 10h, determine the offending qc and acquire + * error status TF. For NCQ device errors, all LLDDs have to do + * is setting AC_ERR_DEV in ehi->err_mask. This function takes + * care of the rest. + * + * LOCKING: + * Kernel thread context (may sleep). + */ +void ata_eh_analyze_ncq_error(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + struct ata_eh_context *ehc = &link->eh_context; + struct ata_device *dev = link->device; + struct ata_queued_cmd *qc; + struct ata_taskfile tf; + int tag, rc; + + /* if frozen, we can't do much */ + if (ap->pflags & ATA_PFLAG_FROZEN) + return; + + /* is it NCQ device error? */ + if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) + return; + + /* has LLDD analyzed already? */ + ata_qc_for_each_raw(ap, qc, tag) { + if (!(qc->flags & ATA_QCFLAG_FAILED)) + continue; + + if (qc->err_mask) + return; + } + + /* okay, this error is ours */ + memset(&tf, 0, sizeof(tf)); + rc = ata_eh_read_log_10h(dev, &tag, &tf); + if (rc) { + ata_link_err(link, "failed to read log page 10h (errno=%d)\n", + rc); + return; + } + + if (!(link->sactive & (1 << tag))) { + ata_link_err(link, "log page 10h reported inactive tag %d\n", + tag); + return; + } + + /* we've got the perpetrator, condemn it */ + qc = __ata_qc_from_tag(ap, tag); + memcpy(&qc->result_tf, &tf, sizeof(tf)); + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; + qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; + if (dev->class == ATA_DEV_ZAC && + ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { + char sense_key, asc, ascq; + + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; + asc = (qc->result_tf.auxiliary >> 8) & 0xff; + ascq = qc->result_tf.auxiliary & 0xff; + ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); + ata_scsi_set_sense_information(dev, qc->scsicmd, + &qc->result_tf); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + } + + ehc->i.err_mask &= ~AC_ERR_DEV; +} +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); diff --git a/include/linux/libata.h b/include/linux/libata.h index 9c7ca659dc94..cffa4714bfa8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1181,6 +1181,7 @@ extern int sata_link_hardreset(struct ata_link *link, 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) @@ -1217,6 +1218,7 @@ static inline int sata_link_resume(struct ata_link *link, { 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); @@ -1339,7 +1341,6 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_eh_analyze_ncq_error(struct ata_link *link); extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, From bf89b0bf3038cdc972b563b16c68cee1b8eefb31 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 Mar 2020 16:58:22 +0100 Subject: [PATCH 36/36] ata: make "libata.force" kernel parameter optional Add ATA_FORCE config option (visible only if EXPERT config option is enabled) and make "libata.force" kernel parameter optional. Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename w/ CONFIG_ATA_FORCE=y: 31983 572 40 32595 7f53 drivers/ata/libata-core.o w/ CONFIG_ATA_FROCE=n: 28958 316 32 29306 727a drivers/ata/libata-core.o Suggested-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/ata/Kconfig | 16 ++++++++++++++++ drivers/ata/libata-core.c | 22 ++++++++++++++++++++-- drivers/ata/libata.h | 4 ++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5b55ebf56b5a..05ecdce1b702 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -51,6 +51,22 @@ 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 + . + + 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 diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 20c22dbc1f24..beca5f91bb4c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -89,6 +89,7 @@ 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; u8 cbl; @@ -112,6 +113,7 @@ 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); @@ -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 @@ -6080,6 +6088,7 @@ int ata_platform_remove_one(struct platform_device *pdev) } 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) @@ -6259,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; @@ -6267,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; } @@ -6291,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); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 6c808cf39135..68cdd81d747c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -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);