From patchwork Tue Oct 3 11:59:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartlomiej Zolnierkiewicz X-Patchwork-Id: 820870 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ide-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3y5yHl2p50z9t2Z for ; Tue, 3 Oct 2017 22:59:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751566AbdJCL7O (ORCPT ); Tue, 3 Oct 2017 07:59:14 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:10504 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751421AbdJCL7M (ORCPT ); Tue, 3 Oct 2017 07:59:12 -0400 Received: from epcas2p2.samsung.com (unknown [182.195.41.54]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20171003115910epoutp044a361a5a5f0892f8dd3782d484f33613~qDZMdQVeG2937629376epoutp04i; Tue, 3 Oct 2017 11:59:10 +0000 (GMT) Received: from epsmges2p4.samsung.com (unknown [182.195.42.72]) by epcas2p3.samsung.com (KnoxPortal) with ESMTP id 20171003115910epcas2p39b685675cb2a08dbf6eaa5cf9cec49e7~qDZL0b4Dj0230802308epcas2p3X; Tue, 3 Oct 2017 11:59:10 +0000 (GMT) Received: from epcas2p1.samsung.com ( [182.195.41.53]) by epsmges2p4.samsung.com (Symantec Messaging Gateway) with SMTP id 3F.73.04101.E8B73D95; Tue, 3 Oct 2017 20:59:10 +0900 (KST) Received: from epsmgms2p2new.samsung.com (unknown [182.195.42.143]) by epcas2p2.samsung.com (KnoxPortal) with ESMTP id 20171003115909epcas2p21c25b1c67678df6fd6c26386345abf9a~qDZLauDIS0328803288epcas2p2s; Tue, 3 Oct 2017 11:59:09 +0000 (GMT) X-AuditID: b6c32a48-c27ff70000001005-26-59d37b8e2a81 Received: from epmmp2 ( [203.254.227.17]) by epsmgms2p2new.samsung.com (Symantec Messaging Gateway) with SMTP id AF.E8.06856.D8B73D95; Tue, 3 Oct 2017 20:59:09 +0900 (KST) Received: from amdc3058.localnet ([106.120.53.102]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OX8007T0XAK6720@mmp2.samsung.com>; Tue, 03 Oct 2017 20:59:09 +0900 (KST) From: Bartlomiej Zolnierkiewicz To: "David S. Miller" Cc: Guenter Roeck , Lorenzo Pieralisi , Bjorn Helgaas , Richard Henderson , Ivan Kokshaysky , Matt Turner , linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] ide: pci: free PCI BARs on initialization failure Date: Tue, 03 Oct 2017 13:59:07 +0200 Message-id: <3105781.uZB2mYxEDh@amdc3058> User-Agent: KMail/4.13.3 (Linux/3.13.0-96-generic; KDE/4.13.3; x86_64; ; ) MIME-version: 1.0 Content-transfer-encoding: 7Bit Content-type: text/plain; charset="us-ascii" X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42LZdljTVLev+nKkwb6jrBZLmjIs5pxvYbH4 d2ojs8WxHY+YLC7vmsNm8WThGSaLN79fsFt8un2Q2WLaqTusDpwea+atYfTYsvImk8fOWXfZ PRZsKvX4fzbKY+f3BnaPvukfmD0+b5IL4IjisklJzcksSy3St0vgyvjfl1cwS6fiw7XlTA2M 35S6GDk5JARMJFZMnMPexcjFISSwg1HiU+tvJgjnO6PEvWf7gDIcYFW90wUg4hsYJZYtXsYC 4XxllLi1Yys7yCg2ASuJie2rGEFsEQFtiXUHelhBipgF1jFJHNj/mxFkkrCAk8TVv+YgNSwC qhKtk5czgdi8ApoSTa/2gNmiAl4SW/a1Q8UFJX5MvscCYjMLyEvs2z+VFcLWkTh7bB0jyHwJ gSNsEkdmT2WD+MdFoqnnMiOELSzx6vgWdghbWuLZqo1Q8emMEtt/S0A0b2aUWLV7AlSRtcTh 4xehNvBJdBz+C/U+r0RHmxBEiYfEiwc9bBBhR4mu9/UgYSGBWIlzSx8yT2CUmYXk7FlIzp6F 5OwFjMyrGMVSC4pz01OLjQpM9IoTc4tL89L1kvNzNzGCk4aWxw7GA+d8DjEKcDAq8fAmuF2K FGJNLCuuzD3EKMHBrCTCa1J5OVKINyWxsiq1KD++qDQntfgQozQHi5I4b922axFCAumJJanZ qakFqUUwWSYOTqkGxrYcD/58rt9+xhNbH6YfFM+Tlbn03WFW+zpX2/0Zqw54ynPz32PaNe/v /pSEZ51nT83Zq3yt5rDrIwsXd5EzFqmqB1wUrm/uXS1veCqtV25W1of7jgc2bLqVuEsydeXe DZxvuvgsv0kmHP96X63l3vIz3g7sP1m+X1O4HHm73c4qTFLn4e1gTSWW4oxEQy3mouJEADTV jRYWAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrPLMWRmVeSWpSXmKPExsVy+t9jQd3e6suRBv171SyWNGVYzDnfwmLx 79RGZotjOx4xWVzeNYfN4snCM0wWb36/YLf4dPsgs8W0U3dYHTg91sxbw+ixZeVNJo+ds+6y eyzYVOrx/2yUx87vDewefdM/MHt83iQXwBHFZZOSmpNZllqkb5fAlfG/L69glk7Fh2vLmRoY vyl1MXJwSAiYSPROF+hi5OIQEljHKLH/613WLkZOIOcro8SkzlAQm03ASmJi+ypGEFtEQFti 3YEeVpAGZoF1TBLbp7WzggwSFnCSuPrXHKSGRUBVonXyciYQm1dAU6Lp1R4wW1TAS2LLvnao uKDEj8n3WEBsZgF5iX37p7JC2FoS63ceZ5rAyDsLSdksJGWzkJQtYGRexSiZWlCcm55bbFRg lJdarlecmFtcmpeul5yfu4kRGMzbDmv172B8vCT+EKMAB6MSD+8Oj0uRQqyJZcWVuYcYJTiY lUR4X1VdjhTiTUmsrEotyo8vKs1JLT7EKM3BoiTOy59/LFJIID2xJDU7NbUgtQgmy8TBKdXA uHfynZ137XQlTZ5VsH9fzRT1eN1tMbXQtOamk4vYv+qumX3a5ULhu7T3+6/Pi5MrabuvKx7o IsKnybWriqm96rZpykOZ+7O+TOop+bK7pDzrhoedTMXuuGefucNKVvwJvJfW+7Ttvol59+fk Ds7HM17qP7zqZSko0tuk9dl724HtesfjT/p8U2Ipzkg01GIuKk4EADz6YttiAgAA X-CMS-MailID: 20171003115909epcas2p21c25b1c67678df6fd6c26386345abf9a X-Msg-Generator: CA X-Sender-IP: 182.195.42.143 X-Local-Sender: =?utf-8?q?Bartlomiej_Zolnierkiewicz=1BSRPOL-Kernel_=28TP?= =?utf-8?b?KRvsgrzshLHsoITsnpAbU2VuaW9yIFNvZnR3YXJlIEVuZ2luZWVy?= X-Global-Sender: =?utf-8?q?Bartlomiej_Zolnierkiewicz=1BSRPOL-Kernel_=28TP?= =?utf-8?q?=29=1BSamsung_Electronics=1BSenior_Software_Engineer?= X-Sender-Code: =?utf-8?q?C10=1BEHQ=1BC10CD02CD027392?= CMS-TYPE: 102P X-CMS-RootMailID: 20171003115909epcas2p21c25b1c67678df6fd6c26386345abf9a X-RootMTR: 20171003115909epcas2p21c25b1c67678df6fd6c26386345abf9a References: Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org Recent pci_assign_irq() changes uncovered a problem with missing freeing of PCI BARs on PCI IDE host initialization failure: ide0: disabled, no IRQ ide0: failed to initialize IDE interface ide0: disabling port cmd64x 0000:00:02.0: IDE controller (0x1095:0x0646 rev 0x07) CMD64x_IDE 0000:00:02.0: BAR 0: can't reserve [io 0x8050-0x8057] cmd64x 0000:00:02.0: can't reserve resources CMD64x_IDE: probe of 0000:00:02.0 failed with error -16 Fix the problem by adding missing freeing of PCI BARs to ide_setup_pci_controller() and ide_pci_init_two(). Link: http://lkml.kernel.org/r/32ec730f-c1b0-5584-cd35-f8a809122b96@roeck-us.net Reported-by: Guenter Roeck Cc: Bjorn Helgaas Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Guenter Roeck Cc: Matt Turner Signed-off-by: Bartlomiej Zolnierkiewicz --- This should fix problem with reserving PCI resources on a secondary PCI device probe attempt (please test when pci_assign_irq() fix is not present and "[PATCH] ide: add missing hwif->portdev freeing on hwif_init() failure" is applied). drivers/ide/setup-pci.c | 61 +++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 23 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: b/drivers/ide/setup-pci.c =================================================================== --- a/drivers/ide/setup-pci.c 2017-10-03 13:43:29.567778114 +0200 +++ b/drivers/ide/setup-pci.c 2017-10-03 13:43:54.131778138 +0200 @@ -179,6 +179,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); /** * ide_pci_enable - do PCI enables * @dev: PCI device + * @bars: PCI BARs mask * @d: IDE port info * * Enable the IDE PCI device. We attempt to enable the device in full @@ -189,9 +190,10 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); * Returns zero on success or an error code */ -static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) +static int ide_pci_enable(struct pci_dev *dev, int bars, + const struct ide_port_info *d) { - int ret, bars; + int ret; if (pci_enable_device(dev)) { ret = pci_enable_device_io(dev); @@ -216,18 +218,6 @@ static int ide_pci_enable(struct pci_dev goto out; } - if (d->host_flags & IDE_HFLAG_SINGLE) - bars = (1 << 2) - 1; - else - bars = (1 << 4) - 1; - - if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { - if (d->host_flags & IDE_HFLAG_CS5520) - bars |= (1 << 2); - else - bars |= (1 << 4); - } - ret = pci_request_selected_regions(dev, bars, d->name); if (ret < 0) printk(KERN_ERR "%s %s: can't reserve resources\n", @@ -403,6 +393,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, /** * ide_setup_pci_controller - set up IDE PCI * @dev: PCI device + * @bars: PCI BARs mask * @d: IDE port info * @noisy: verbose flag * @@ -411,7 +402,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, * and enables it if need be */ -static int ide_setup_pci_controller(struct pci_dev *dev, +static int ide_setup_pci_controller(struct pci_dev *dev, int bars, const struct ide_port_info *d, int noisy) { int ret; @@ -420,7 +411,7 @@ static int ide_setup_pci_controller(stru if (noisy) ide_setup_pci_noise(dev, d); - ret = ide_pci_enable(dev, d); + ret = ide_pci_enable(dev, bars, d); if (ret < 0) goto out; @@ -428,16 +419,18 @@ static int ide_setup_pci_controller(stru if (ret < 0) { printk(KERN_ERR "%s %s: error accessing PCI regs\n", d->name, pci_name(dev)); - goto out; + goto out_free_bars; } if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ ret = ide_pci_configure(dev, d); if (ret < 0) - goto out; + goto out_free_bars; printk(KERN_INFO "%s %s: device enabled (Linux)\n", d->name, pci_name(dev)); } +out_free_bars: + pci_release_selected_regions(dev, bars); out: return ret; } @@ -540,13 +533,28 @@ int ide_pci_init_two(struct pci_dev *dev { struct pci_dev *pdev[] = { dev1, dev2 }; struct ide_host *host; - int ret, i, n_ports = dev2 ? 4 : 2; + int ret, i, n_ports = dev2 ? 4 : 2, bars; struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; + if (d->host_flags & IDE_HFLAG_SINGLE) + bars = (1 << 2) - 1; + else + bars = (1 << 4) - 1; + + if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { + if (d->host_flags & IDE_HFLAG_CS5520) + bars |= (1 << 2); + else + bars |= (1 << 4); + } + for (i = 0; i < n_ports / 2; i++) { - ret = ide_setup_pci_controller(pdev[i], d, !i); - if (ret < 0) + ret = ide_setup_pci_controller(pdev[i], bars, d, !i); + if (ret < 0) { + if (i == 1) + pci_release_selected_regions(pdev[0], bars); goto out; + } ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); } @@ -554,7 +562,7 @@ int ide_pci_init_two(struct pci_dev *dev host = ide_host_alloc(d, hws, n_ports); if (host == NULL) { ret = -ENOMEM; - goto out; + goto out_free_bars; } host->dev[0] = &dev1->dev; @@ -576,7 +584,7 @@ int ide_pci_init_two(struct pci_dev *dev * do_ide_setup_pci_device() on the first device! */ if (ret < 0) - goto out; + goto out_free_bars; /* fixup IRQ */ if (ide_pci_is_in_compatibility_mode(pdev[i])) { @@ -589,6 +597,13 @@ int ide_pci_init_two(struct pci_dev *dev ret = ide_host_register(host, d, hws); if (ret) ide_host_free(host); + else + goto out; + +out_free_bars: + i = n_ports / 2; + while (i--) + pci_release_selected_regions(pdev[i], bars); out: return ret; }