The ufs support consists with the core driver (ufshcd) and the actual glue driver (ufshcd-pci or ufshcd-pltfrm). The module reference of this scsi host is initialized to the core driver's one. Because the glue drivers use ufshcd_alloc_host() which is defined in ufshcd module and calls scsi_host_alloc(). So the glue drivers can be unloaded even if the scsi device is being accessed. This fixes it by converting ufshcd_alloc_host() into macro so that the glue drivers can pass their correct module reference through __scsi_host_alloc(). Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx> Cc: Vinayak Holikatti <vinholikatti@xxxxxxxxx> Cc: Dolev Raviv <draviv@xxxxxxxxxxxxxx> Cc: Sujit Reddy Thumma <sthumma@xxxxxxxxxxxxxx> Cc: Subhash Jadavani <subhashj@xxxxxxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: "James E.J. Bottomley" <JBottomley@xxxxxxxxxxxxx> Cc: linux-scsi@xxxxxxxxxxxxxxx --- drivers/scsi/ufs/ufshcd.c | 13 +++++++------ drivers/scsi/ufs/ufshcd.h | 5 ++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2e26025..59a4855 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4202,7 +4202,6 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) } static struct scsi_host_template ufshcd_driver_template = { - .module = THIS_MODULE, .name = UFSHCD, .proc_name = UFSHCD, .queuecommand = ufshcd_queuecommand, @@ -5256,12 +5255,14 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) } /** - * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) + * __ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle * @hba_handle: driver private handle + * @owner: module which will be the owner of the scsi host * Returns 0 on success, non-zero value on failure */ -int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) +int __ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle, + struct module *owner) { struct Scsi_Host *host; struct ufs_hba *hba; @@ -5274,8 +5275,8 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) goto out_error; } - host = scsi_host_alloc(&ufshcd_driver_template, - sizeof(struct ufs_hba)); + host = __scsi_host_alloc(&ufshcd_driver_template, + sizeof(struct ufs_hba), owner); if (!host) { dev_err(dev, "scsi_host_alloc failed\n"); err = -ENOMEM; @@ -5289,7 +5290,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) out_error: return err; } -EXPORT_SYMBOL(ufshcd_alloc_host); +EXPORT_SYMBOL(__ufshcd_alloc_host); static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 4a574aa..ac7d72f 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -515,7 +515,10 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) ufshcd_writel(hba, tmp, reg); } -int ufshcd_alloc_host(struct device *, struct ufs_hba **); +int __ufshcd_alloc_host(struct device *, struct ufs_hba **, + struct module *owner); +#define ufshcd_alloc_host(dev, hba_handle) \ + __ufshcd_alloc_host(dev, hba_handle, THIS_MODULE) int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); void ufshcd_remove(struct ufs_hba *); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html