From patchwork Sat Aug 1 17:19:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 6922531 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E0F70C05AC for ; Sat, 1 Aug 2015 17:20:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C8BE7202B8 for ; Sat, 1 Aug 2015 17:20:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7778B20532 for ; Sat, 1 Aug 2015 17:20:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751473AbbHARUH (ORCPT ); Sat, 1 Aug 2015 13:20:07 -0400 Received: from mail-pd0-f175.google.com ([209.85.192.175]:34699 "EHLO mail-pd0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751015AbbHARUE (ORCPT ); Sat, 1 Aug 2015 13:20:04 -0400 Received: by pdbbh15 with SMTP id bh15so56483330pdb.1 for ; Sat, 01 Aug 2015 10:20:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0T+0iV0c+m3IpUtlEj0U9u3YSBaCHBT1tO+nC41cXaM=; b=tiepJzzZY1ykmG4HqJWkfln7ogYwnz1qistO/GLGd1E+PD/3cMrZ/peOs5CEcZ4Xm3 K7/AXA1gZyn2WOUWijWQMFBvbyTLJ5D+is6b1KY+WAhFjbWrC8JVISdyWT9BxBniiTN3 /XnopyX4gij9jdHvz8vbL2xMRc5onB4mWC5YbZnE+QV0j/phLNONFqsxVD/bVCQLZHLe 6DFLJKV4BC+4VM8psOjTABmIw/Khr96tFBH1DxnRpw1tHeXBreq8tHr1lJQCTbQMu6Lg oJGpfYZFMRm5GKCJDXnYYAwPraKO5IiCKEY6UGMqvgCUQTAZdf5K7layJqQMgBa6BOpN cK1A== X-Received: by 10.70.136.129 with SMTP id qa1mr19569979pdb.81.1438449603866; Sat, 01 Aug 2015 10:20:03 -0700 (PDT) Received: from localhost.localdomain (KD113159139091.ppp-bb.dion.ne.jp. [113.159.139.91]) by smtp.gmail.com with ESMTPSA id tm3sm12259153pac.44.2015.08.01.10.20.00 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 01 Aug 2015 10:20:03 -0700 (PDT) From: Akinobu Mita To: linux-scsi@vger.kernel.org Cc: Akinobu Mita , Vinayak Holikatti , Dolev Raviv , Sujit Reddy Thumma , Subhash Jadavani , Christoph Hellwig , "James E.J. Bottomley" Subject: [PATCH v2 6/6] scsi: ufs: fix module reference for scsi host Date: Sun, 2 Aug 2015 02:19:20 +0900 Message-Id: <1438449560-4106-7-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1438449560-4106-1-git-send-email-akinobu.mita@gmail.com> References: <1438449560-4106-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP While accessing a UFS device, the module reference count for core driver (ufshcd) is incremented but not incremented for the actual glue driver (ufshcd-pci or ufshcd-pltfrm). Because these drivers allocate scsi hosts with scsi_host_template defined in ufshcd module. So these drivers always can be unloaded. This fixes it by preparing scsi host template which is initialized at module_init() for each ufs glue driver. Signed-off-by: Akinobu Mita Cc: Vinayak Holikatti Cc: Dolev Raviv Cc: Sujit Reddy Thumma Cc: Subhash Jadavani Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: linux-scsi@vger.kernel.org --- drivers/scsi/ufs/ufshcd-pci.c | 19 +++++++++++++++++-- drivers/scsi/ufs/ufshcd-pltfrm.c | 19 +++++++++++++++++-- drivers/scsi/ufs/ufshcd.c | 19 +++++++++++++++---- drivers/scsi/ufs/ufshcd.h | 5 ++++- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index d15eaa4..961c4ad 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -106,6 +106,8 @@ static void ufshcd_pci_remove(struct pci_dev *pdev) ufshcd_remove(hba); } +static struct scsi_host_template ufshcd_pci_host_template; + /** * ufshcd_pci_probe - probe routine of the driver * @pdev: pointer to PCI device handle @@ -136,7 +138,7 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mmio_base = pcim_iomap_table(pdev)[0]; - err = ufshcd_alloc_host(&pdev->dev, &hba); + err = ufshcd_alloc_host(&pdev->dev, &ufshcd_pci_host_template, &hba); if (err) { dev_err(&pdev->dev, "Allocation failed\n"); return err; @@ -183,7 +185,20 @@ static struct pci_driver ufshcd_pci_driver = { }, }; -module_pci_driver(ufshcd_pci_driver); +static int __init ufshcd_pci_driver_init(void) +{ + ufshcd_host_template_init(&ufshcd_pci_host_template, "ufshcd-pci", + THIS_MODULE); + + return pci_register_driver(&ufshcd_pci_driver); +} +module_init(ufshcd_pci_driver_init); + +static void __exit ufshcd_pci_driver_exit(void) +{ + pci_unregister_driver(&ufshcd_pci_driver); +} +module_exit(ufshcd_pci_driver_exit); MODULE_AUTHOR("Santosh Yaragnavi "); MODULE_AUTHOR("Vinayak Holikatti "); diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 12f1246..2a137c2 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -287,6 +287,8 @@ static void ufshcd_pltfrm_shutdown(struct platform_device *pdev) ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); } +static struct scsi_host_template ufshcd_pltfrm_host_template; + /** * ufshcd_pltfrm_probe - probe routine of the driver * @pdev: pointer to Platform device handle @@ -315,7 +317,7 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) goto out; } - err = ufshcd_alloc_host(dev, &hba); + err = ufshcd_alloc_host(dev, &ufshcd_pltfrm_host_template, &hba); if (err) { dev_err(&pdev->dev, "Allocation failed\n"); goto out; @@ -400,7 +402,20 @@ static struct platform_driver ufshcd_pltfrm_driver = { }, }; -module_platform_driver(ufshcd_pltfrm_driver); +static int __init ufshcd_pltfrm_driver_init(void) +{ + ufshcd_host_template_init(&ufshcd_pltfrm_host_template, "ufshcd-pltfrm", + THIS_MODULE); + + return platform_driver_register(&ufshcd_pltfrm_driver); +} +module_init(ufshcd_pltfrm_driver_init); + +static void __exit ufshcd_pltfrm_driver_exit(void) +{ + platform_driver_unregister(&ufshcd_pltfrm_driver); +} +module_exit(ufshcd_pltfrm_driver_exit); MODULE_AUTHOR("Santosh Yaragnavi "); MODULE_AUTHOR("Vinayak Holikatti "); diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d287207..6fa64bd 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4338,7 +4338,7 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) ufshcd_probe_hba(hba); } -static struct scsi_host_template ufshcd_driver_template = { +static const struct scsi_host_template ufshcd_driver_template = { .module = THIS_MODULE, .name = UFSHCD, .proc_name = UFSHCD, @@ -4359,6 +4359,16 @@ static struct scsi_host_template ufshcd_driver_template = { .track_queue_depth = 1, }; +void ufshcd_host_template_init(struct scsi_host_template *sht, const char *name, + struct module *owner) +{ + *sht = ufshcd_driver_template; + sht->name = name; + sht->proc_name = name; + sht->module = owner; +} +EXPORT_SYMBOL_GPL(ufshcd_host_template_init); + static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, int ua) { @@ -5388,10 +5398,12 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) /** * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle + * @sht: scsi_host_template to use when registering the host * @hba_handle: driver private handle * 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 scsi_host_template *sht, + struct ufs_hba **hba_handle) { struct Scsi_Host *host; struct ufs_hba *hba; @@ -5404,8 +5416,7 @@ 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(sht, sizeof(struct ufs_hba)); if (!host) { dev_err(dev, "scsi_host_alloc failed\n"); err = -ENOMEM; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index c40a0e7..cad15b0 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -575,7 +575,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 **); +void ufshcd_host_template_init(struct scsi_host_template *sht, const char *name, + struct module *owner); +int ufshcd_alloc_host(struct device *, struct scsi_host_template *, + struct ufs_hba **); int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); void ufshcd_remove(struct ufs_hba *);