Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 018d5ef2 authored by Akinobu Mita's avatar Akinobu Mita Committed by Tejun Heo
Browse files

ata: ahci_platform: fix owner module reference mismatch for scsi host



The owner module reference of the ahci platform's scsi_host is
initialized to libahci_platform's one, because these drivers use a
scsi_host_template defined in libahci_platform.  So these drivers can
be unloaded even if the scsi device is being accessed.

This fixes it by pushing the scsi_host_template from libahci_platform
to all leaf drivers.  The scsi_host_template is passed through a new
argument of ahci_platform_init_host().

Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: linux-ide@vger.kernel.org
Cc: linux-scsi@vger.kernel.org
parent cedda4c3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -354,6 +354,10 @@ extern int ahci_ignore_sss;
extern struct device_attribute *ahci_shost_attrs[];
extern struct device_attribute *ahci_sdev_attrs[];

/*
 * This must be instantiated by the edge drivers.  Read the comments
 * for ATA_BASE_SHT
 */
#define AHCI_SHT(drv_name)						\
	ATA_NCQ_SHT(drv_name),						\
	.can_queue		= AHCI_MAX_CMDS - 1,			\
+9 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <linux/ahci_platform.h>
#include "ahci.h"

#define DRV_NAME "ahci_da850"

/* SATA PHY Control Register offset from AHCI base */
#define SATA_P0PHYCR_REG	0x178

@@ -59,6 +61,10 @@ static const struct ata_port_info ahci_da850_port_info = {
	.port_ops	= &ahci_platform_ops,
};

static struct scsi_host_template ahci_platform_sht = {
	AHCI_SHT(DRV_NAME),
};

static int ahci_da850_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -85,7 +91,8 @@ static int ahci_da850_probe(struct platform_device *pdev)

	da850_sata_init(dev, pwrdn_reg, hpriv->mmio);

	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info);
	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
				     &ahci_platform_sht);
	if (rc)
		goto disable_resources;

@@ -102,7 +109,7 @@ static struct platform_driver ahci_da850_driver = {
	.probe = ahci_da850_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = "ahci_da850",
		.name = DRV_NAME,
		.pm = &ahci_da850_pm_ops,
	},
};
+9 −2
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@
#include <linux/libata.h>
#include "ahci.h"

#define DRV_NAME "ahci-imx"

enum {
	/* Timer 1-ms Register */
	IMX_TIMER1MS				= 0x00e0,
@@ -520,6 +522,10 @@ static u32 imx_ahci_parse_props(struct device *dev,
	return reg_value;
}

static struct scsi_host_template ahci_platform_sht = {
	AHCI_SHT(DRV_NAME),
};

static int imx_ahci_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -616,7 +622,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
	reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
	writel(reg_val, hpriv->mmio + IMX_TIMER1MS);

	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info);
	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
				      &ahci_platform_sht);
	if (ret)
		goto disable_sata;

@@ -674,7 +681,7 @@ static struct platform_driver imx_ahci_driver = {
	.probe = imx_ahci_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = "ahci-imx",
		.name = DRV_NAME,
		.of_match_table = imx_ahci_of_match,
		.pm = &ahci_imx_pm_ops,
	},
+9 −2
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/platform_device.h>
#include "ahci.h"

#define DRV_NAME "ahci-mvebu"

#define AHCI_VENDOR_SPECIFIC_0_ADDR  0xa0
#define AHCI_VENDOR_SPECIFIC_0_DATA  0xa4

@@ -67,6 +69,10 @@ static const struct ata_port_info ahci_mvebu_port_info = {
	.port_ops  = &ahci_platform_ops,
};

static struct scsi_host_template ahci_platform_sht = {
	AHCI_SHT(DRV_NAME),
};

static int ahci_mvebu_probe(struct platform_device *pdev)
{
	struct ahci_host_priv *hpriv;
@@ -88,7 +94,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
	ahci_mvebu_mbus_config(hpriv, dram);
	ahci_mvebu_regret_option(hpriv);

	rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info);
	rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info,
				     &ahci_platform_sht);
	if (rc)
		goto disable_resources;

@@ -114,7 +121,7 @@ static struct platform_driver ahci_mvebu_driver = {
	.probe = ahci_mvebu_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = "ahci-mvebu",
		.name = DRV_NAME,
		.of_match_table = ahci_mvebu_of_match,
	},
};
+9 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/ahci_platform.h>
#include "ahci.h"

#define DRV_NAME "ahci"

static const struct ata_port_info ahci_port_info = {
	.flags		= AHCI_FLAG_COMMON,
	.pio_mask	= ATA_PIO4,
@@ -29,6 +31,10 @@ static const struct ata_port_info ahci_port_info = {
	.port_ops	= &ahci_platform_ops,
};

static struct scsi_host_template ahci_platform_sht = {
	AHCI_SHT(DRV_NAME),
};

static int ahci_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -46,7 +52,8 @@ static int ahci_probe(struct platform_device *pdev)
	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
		hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;

	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info);
	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
				     &ahci_platform_sht);
	if (rc)
		goto disable_resources;

@@ -75,7 +82,7 @@ static struct platform_driver ahci_driver = {
	.probe = ahci_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = "ahci",
		.name = DRV_NAME,
		.of_match_table = ahci_of_match,
		.pm = &ahci_pm_ops,
	},
Loading