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

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
...@@ -354,6 +354,10 @@ extern int ahci_ignore_sss; ...@@ -354,6 +354,10 @@ extern int ahci_ignore_sss;
extern struct device_attribute *ahci_shost_attrs[]; extern struct device_attribute *ahci_shost_attrs[];
extern struct device_attribute *ahci_sdev_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) \ #define AHCI_SHT(drv_name) \
ATA_NCQ_SHT(drv_name), \ ATA_NCQ_SHT(drv_name), \
.can_queue = AHCI_MAX_CMDS - 1, \ .can_queue = AHCI_MAX_CMDS - 1, \
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/ahci_platform.h> #include <linux/ahci_platform.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "ahci_da850"
/* SATA PHY Control Register offset from AHCI base */ /* SATA PHY Control Register offset from AHCI base */
#define SATA_P0PHYCR_REG 0x178 #define SATA_P0PHYCR_REG 0x178
...@@ -59,6 +61,10 @@ static const struct ata_port_info ahci_da850_port_info = { ...@@ -59,6 +61,10 @@ static const struct ata_port_info ahci_da850_port_info = {
.port_ops = &ahci_platform_ops, .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) static int ahci_da850_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -85,7 +91,8 @@ static int ahci_da850_probe(struct platform_device *pdev) ...@@ -85,7 +91,8 @@ static int ahci_da850_probe(struct platform_device *pdev)
da850_sata_init(dev, pwrdn_reg, hpriv->mmio); 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) if (rc)
goto disable_resources; goto disable_resources;
...@@ -102,7 +109,7 @@ static struct platform_driver ahci_da850_driver = { ...@@ -102,7 +109,7 @@ static struct platform_driver ahci_da850_driver = {
.probe = ahci_da850_probe, .probe = ahci_da850_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "ahci_da850", .name = DRV_NAME,
.pm = &ahci_da850_pm_ops, .pm = &ahci_da850_pm_ops,
}, },
}; };
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <linux/libata.h> #include <linux/libata.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "ahci-imx"
enum { enum {
/* Timer 1-ms Register */ /* Timer 1-ms Register */
IMX_TIMER1MS = 0x00e0, IMX_TIMER1MS = 0x00e0,
...@@ -520,6 +522,10 @@ static u32 imx_ahci_parse_props(struct device *dev, ...@@ -520,6 +522,10 @@ static u32 imx_ahci_parse_props(struct device *dev,
return reg_value; return reg_value;
} }
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
static int imx_ahci_probe(struct platform_device *pdev) static int imx_ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -616,7 +622,8 @@ static int imx_ahci_probe(struct platform_device *pdev) ...@@ -616,7 +622,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
writel(reg_val, hpriv->mmio + IMX_TIMER1MS); 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) if (ret)
goto disable_sata; goto disable_sata;
...@@ -674,7 +681,7 @@ static struct platform_driver imx_ahci_driver = { ...@@ -674,7 +681,7 @@ static struct platform_driver imx_ahci_driver = {
.probe = imx_ahci_probe, .probe = imx_ahci_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "ahci-imx", .name = DRV_NAME,
.of_match_table = imx_ahci_of_match, .of_match_table = imx_ahci_of_match,
.pm = &ahci_imx_pm_ops, .pm = &ahci_imx_pm_ops,
}, },
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "ahci-mvebu"
#define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 #define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0
#define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 #define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4
...@@ -67,6 +69,10 @@ static const struct ata_port_info ahci_mvebu_port_info = { ...@@ -67,6 +69,10 @@ static const struct ata_port_info ahci_mvebu_port_info = {
.port_ops = &ahci_platform_ops, .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) static int ahci_mvebu_probe(struct platform_device *pdev)
{ {
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
...@@ -88,7 +94,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev) ...@@ -88,7 +94,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
ahci_mvebu_mbus_config(hpriv, dram); ahci_mvebu_mbus_config(hpriv, dram);
ahci_mvebu_regret_option(hpriv); 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) if (rc)
goto disable_resources; goto disable_resources;
...@@ -114,7 +121,7 @@ static struct platform_driver ahci_mvebu_driver = { ...@@ -114,7 +121,7 @@ static struct platform_driver ahci_mvebu_driver = {
.probe = ahci_mvebu_probe, .probe = ahci_mvebu_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "ahci-mvebu", .name = DRV_NAME,
.of_match_table = ahci_mvebu_of_match, .of_match_table = ahci_mvebu_of_match,
}, },
}; };
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <linux/ahci_platform.h> #include <linux/ahci_platform.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "ahci"
static const struct ata_port_info ahci_port_info = { static const struct ata_port_info ahci_port_info = {
.flags = AHCI_FLAG_COMMON, .flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
...@@ -29,6 +31,10 @@ static const struct ata_port_info ahci_port_info = { ...@@ -29,6 +31,10 @@ static const struct ata_port_info ahci_port_info = {
.port_ops = &ahci_platform_ops, .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) static int ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -46,7 +52,8 @@ static int ahci_probe(struct platform_device *pdev) ...@@ -46,7 +52,8 @@ static int ahci_probe(struct platform_device *pdev)
if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; 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) if (rc)
goto disable_resources; goto disable_resources;
...@@ -75,7 +82,7 @@ static struct platform_driver ahci_driver = { ...@@ -75,7 +82,7 @@ static struct platform_driver ahci_driver = {
.probe = ahci_probe, .probe = ahci_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "ahci", .name = DRV_NAME,
.of_match_table = ahci_of_match, .of_match_table = ahci_of_match,
.pm = &ahci_pm_ops, .pm = &ahci_pm_ops,
}, },
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "st_ahci"
#define ST_AHCI_OOBR 0xbc #define ST_AHCI_OOBR 0xbc
#define ST_AHCI_OOBR_WE BIT(31) #define ST_AHCI_OOBR_WE BIT(31)
#define ST_AHCI_OOBR_CWMIN_SHIFT 24 #define ST_AHCI_OOBR_CWMIN_SHIFT 24
...@@ -140,6 +142,10 @@ static const struct ata_port_info st_ahci_port_info = { ...@@ -140,6 +142,10 @@ static const struct ata_port_info st_ahci_port_info = {
.port_ops = &st_ahci_port_ops, .port_ops = &st_ahci_port_ops,
}; };
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
static int st_ahci_probe(struct platform_device *pdev) static int st_ahci_probe(struct platform_device *pdev)
{ {
struct st_ahci_drv_data *drv_data; struct st_ahci_drv_data *drv_data;
...@@ -166,7 +172,8 @@ static int st_ahci_probe(struct platform_device *pdev) ...@@ -166,7 +172,8 @@ static int st_ahci_probe(struct platform_device *pdev)
if (err) if (err)
return err; return err;
err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info); err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
&ahci_platform_sht);
if (err) { if (err) {
ahci_platform_disable_resources(hpriv); ahci_platform_disable_resources(hpriv);
return err; return err;
...@@ -229,7 +236,7 @@ MODULE_DEVICE_TABLE(of, st_ahci_match); ...@@ -229,7 +236,7 @@ MODULE_DEVICE_TABLE(of, st_ahci_match);
static struct platform_driver st_ahci_driver = { static struct platform_driver st_ahci_driver = {
.driver = { .driver = {
.name = "st_ahci", .name = DRV_NAME,
.pm = &st_ahci_pm_ops, .pm = &st_ahci_pm_ops,
.of_match_table = of_match_ptr(st_ahci_match), .of_match_table = of_match_ptr(st_ahci_match),
}, },
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "ahci-sunxi"
/* Insmod parameters */ /* Insmod parameters */
static bool enable_pmp; static bool enable_pmp;
module_param(enable_pmp, bool, 0); module_param(enable_pmp, bool, 0);
...@@ -169,6 +171,10 @@ static const struct ata_port_info ahci_sunxi_port_info = { ...@@ -169,6 +171,10 @@ static const struct ata_port_info ahci_sunxi_port_info = {
.port_ops = &ahci_platform_ops, .port_ops = &ahci_platform_ops,
}; };
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
static int ahci_sunxi_probe(struct platform_device *pdev) static int ahci_sunxi_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -200,7 +206,8 @@ static int ahci_sunxi_probe(struct platform_device *pdev) ...@@ -200,7 +206,8 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
if (!enable_pmp) if (!enable_pmp)
hpriv->flags |= AHCI_HFLAG_NO_PMP; hpriv->flags |= AHCI_HFLAG_NO_PMP;
rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info); rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info,
&ahci_platform_sht);
if (rc) if (rc)
goto disable_resources; goto disable_resources;
...@@ -251,7 +258,7 @@ static struct platform_driver ahci_sunxi_driver = { ...@@ -251,7 +258,7 @@ static struct platform_driver ahci_sunxi_driver = {
.probe = ahci_sunxi_probe, .probe = ahci_sunxi_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "ahci-sunxi", .name = DRV_NAME,
.of_match_table = ahci_sunxi_of_match, .of_match_table = ahci_sunxi_of_match,
.pm = &ahci_sunxi_pm_ops, .pm = &ahci_sunxi_pm_ops,
}, },
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "tegra-ahci"
#define SATA_CONFIGURATION_0 0x180 #define SATA_CONFIGURATION_0 0x180
#define SATA_CONFIGURATION_EN_FPCI BIT(0) #define SATA_CONFIGURATION_EN_FPCI BIT(0)
...@@ -289,6 +291,10 @@ static const struct of_device_id tegra_ahci_of_match[] = { ...@@ -289,6 +291,10 @@ static const struct of_device_id tegra_ahci_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
static int tegra_ahci_probe(struct platform_device *pdev) static int tegra_ahci_probe(struct platform_device *pdev)
{ {
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
...@@ -354,7 +360,8 @@ static int tegra_ahci_probe(struct platform_device *pdev) ...@@ -354,7 +360,8 @@ static int tegra_ahci_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info); ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
&ahci_platform_sht);
if (ret) if (ret)
goto deinit_controller; goto deinit_controller;
...@@ -370,7 +377,7 @@ static struct platform_driver tegra_ahci_driver = { ...@@ -370,7 +377,7 @@ static struct platform_driver tegra_ahci_driver = {
.probe = tegra_ahci_probe, .probe = tegra_ahci_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "tegra-ahci", .name = DRV_NAME,
.of_match_table = tegra_ahci_of_match, .of_match_table = tegra_ahci_of_match,
}, },
/* LP0 suspend support not implemented */ /* LP0 suspend support not implemented */
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include "ahci.h" #include "ahci.h"
#define DRV_NAME "xgene-ahci"
/* Max # of disk per a controller */ /* Max # of disk per a controller */
#define MAX_AHCI_CHN_PERCTR 2 #define MAX_AHCI_CHN_PERCTR 2
...@@ -621,6 +623,10 @@ static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx) ...@@ -621,6 +623,10 @@ static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx)
return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0; return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0;
} }
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME),
};
static int xgene_ahci_probe(struct platform_device *pdev) static int xgene_ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -698,7 +704,8 @@ static int xgene_ahci_probe(struct platform_device *pdev) ...@@ -698,7 +704,8 @@ static int xgene_ahci_probe(struct platform_device *pdev)
skip_clk_phy: skip_clk_phy:
hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info,
&ahci_platform_sht);
if (rc) if (rc)
goto disable_resources; goto disable_resources;
...@@ -720,7 +727,7 @@ static struct platform_driver xgene_ahci_driver = { ...@@ -720,7 +727,7 @@ static struct platform_driver xgene_ahci_driver = {
.probe = xgene_ahci_probe, .probe = xgene_ahci_probe,
.remove = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "xgene-ahci", .name = DRV_NAME,
.of_match_table = xgene_ahci_of_match, .of_match_table = xgene_ahci_of_match,
}, },
}; };
......
...@@ -35,10 +35,6 @@ struct ata_port_operations ahci_platform_ops = { ...@@ -35,10 +35,6 @@ struct ata_port_operations ahci_platform_ops = {
}; };
EXPORT_SYMBOL_GPL(ahci_platform_ops); EXPORT_SYMBOL_GPL(ahci_platform_ops);
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT("ahci_platform"),
};
/** /**
* ahci_platform_enable_phys - Enable PHYs * ahci_platform_enable_phys - Enable PHYs
* @hpriv: host private area to store config values * @hpriv: host private area to store config values
...@@ -494,6 +490,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources); ...@@ -494,6 +490,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
* @pdev: platform device pointer for the host * @pdev: platform device pointer for the host
* @hpriv: ahci-host private data for the host * @hpriv: ahci-host private data for the host
* @pi_template: template for the ata_port_info to use * @pi_template: template for the ata_port_info to use
* @sht: scsi_host_template to use when registering
* *
* This function does all the usual steps needed to bring up an * This function does all the usual steps needed to bring up an
* ahci-platform host, note any necessary resources (ie clks, phys, etc.) * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
...@@ -504,7 +501,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources); ...@@ -504,7 +501,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
*/ */
int ahci_platform_init_host(struct platform_device *pdev, int ahci_platform_init_host(struct platform_device *pdev,
struct ahci_host_priv *hpriv, struct ahci_host_priv *hpriv,
const struct ata_port_info *pi_template) const struct ata_port_info *pi_template,
struct scsi_host_template *sht)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ata_port_info pi = *pi_template; struct ata_port_info pi = *pi_template;
...@@ -588,7 +586,7 @@ int ahci_platform_init_host(struct platform_device *pdev, ...@@ -588,7 +586,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
ahci_init_controller(host); ahci_init_controller(host);
ahci_print_info(host, "platform"); ahci_print_info(host, "platform");
return ahci_host_activate(host, irq, &ahci_platform_sht); return ahci_host_activate(host, irq, sht);
} }
EXPORT_SYMBOL_GPL(ahci_platform_init_host); EXPORT_SYMBOL_GPL(ahci_platform_init_host);
......
...@@ -21,6 +21,7 @@ struct device; ...@@ -21,6 +21,7 @@ struct device;
struct ata_port_info; struct ata_port_info;
struct ahci_host_priv; struct ahci_host_priv;
struct platform_device; struct platform_device;
struct scsi_host_template;
int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
...@@ -32,7 +33,8 @@ struct ahci_host_priv *ahci_platform_get_resources( ...@@ -32,7 +33,8 @@ struct ahci_host_priv *ahci_platform_get_resources(
struct platform_device *pdev); struct platform_device *pdev);
int ahci_platform_init_host(struct platform_device *pdev, int ahci_platform_init_host(struct platform_device *pdev,
struct ahci_host_priv *hpriv, struct ahci_host_priv *hpriv,
const struct ata_port_info *pi_template); const struct ata_port_info *pi_template,
struct scsi_host_template *sht);
int ahci_platform_suspend_host(struct device *dev); int ahci_platform_suspend_host(struct device *dev);
int ahci_platform_resume_host(struct device *dev); int ahci_platform_resume_host(struct device *dev);
......
...@@ -1338,6 +1338,12 @@ extern const struct ata_port_operations ata_base_port_ops; ...@@ -1338,6 +1338,12 @@ extern const struct ata_port_operations ata_base_port_ops;
extern const struct ata_port_operations sata_port_ops; extern const struct ata_port_operations sata_port_ops;
extern struct device_attribute *ata_common_sdev_attrs[]; extern struct device_attribute *ata_common_sdev_attrs[];
/*
* All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated
* by the edge drivers. Because the 'module' field of sht must be the
* 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, \ .module = THIS_MODULE, \
.name = drv_name, \ .name = drv_name, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment