From patchwork Tue Oct 3 12:17:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartlomiej Zolnierkiewicz X-Patchwork-Id: 820875 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 3y5yhf1RQjz9sRW for ; Tue, 3 Oct 2017 23:17:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751137AbdJCMRU (ORCPT ); Tue, 3 Oct 2017 08:17:20 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:61248 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750879AbdJCMRT (ORCPT ); Tue, 3 Oct 2017 08:17:19 -0400 Received: from epcas2p3.samsung.com (unknown [182.195.41.55]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20171003121717epoutp03f67d1bcd12311a8a4200155039aaaa0b~qDpA4j2qd0967709677epoutp03K; Tue, 3 Oct 2017 12:17:17 +0000 (GMT) Received: from epsmges2p2.samsung.com (unknown [182.195.42.70]) by epcas2p3.samsung.com (KnoxPortal) with ESMTP id 20171003121716epcas2p3390ea28e43603b73ffcb196a7f26f196~qDo-nvMaF0080600806epcas2p3a; Tue, 3 Oct 2017 12:17:16 +0000 (GMT) Received: from epcas2p2.samsung.com ( [182.195.41.54]) by epsmges2p2.samsung.com (Symantec Messaging Gateway) with SMTP id 1A.03.04435.CCF73D95; Tue, 3 Oct 2017 21:17:16 +0900 (KST) Received: from epsmgms2p2new.samsung.com (unknown [182.195.42.143]) by epcas2p2.samsung.com (KnoxPortal) with ESMTP id 20171003121716epcas2p293688077d6d66b6393f029981adb6108~qDo-Mvg9K1271312713epcas2p2j; Tue, 3 Oct 2017 12:17:16 +0000 (GMT) X-AuditID: b6c32a46-ab3ff70000001153-a5-59d37fcc7ae1 Received: from epmmp1.local.host ( [203.254.227.16]) by epsmgms2p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 32.79.06856.BCF73D95; Tue, 3 Oct 2017 21:17:15 +0900 (KST) Received: from amdc3058.localnet ([106.120.53.102]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OX8008H0Y4QMF30@mmp1.samsung.com>; Tue, 03 Oct 2017 21:17:15 +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 v2] ide: pci: free PCI BARs on initialization failure Date: Tue, 03 Oct 2017 14:17:13 +0200 Message-id: <2124910.9XpgDMsQpd@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+NgFmpjleLIzCtJLcpLzFFi42LZdljTTPdM/eVIg77LchZLmjIs5pxvYbH4 d2ojs8WxHY+YLC7vmsNm8WThGSaLN79fsFt8un2Q2WLaqTusDpwea+atYfTYsvImk8fOWXfZ PRZsKvX4fzbKY+f3BnaPvukfmD0+b5IL4IjisklJzcksSy3St0vgypg+9wBzwRudir6/h1kb GLcpdzFyckgImEj0z/rB3sXIxSEksINR4sfTlcwQzndGiVNzJ7LCVD3adgTMFhLYzSgxbYID RNFXRolDB3rYQBJsAlYSE9tXMYLYIgLaEusO9LCCFDELrGOSOLD/N1hCWMBVYvrsg0wgNouA qsT+Q5vA4rwCmhJLXu9iAbFFBbwktuxrZ4KIC0r8mHwPLM4sIC+xb/9UVghbR+LssXWMIAsk BE6wSbR+nswEcaqLxKuJn6DOFpZ4dXwLO4QtLfFs1UZGCHs6o8T23xIQzZsZJVbtngBVZC1x +PhFqA18Eh2H/wLFOYDivBIdbUIQJR4SC3/dhtrlKNHTvQQaLLESB4++Z5vAKDMLyd2zkNw9 C8ndCxiZVzGKpRYU56anFhsVGOkVJ+YWl+al6yXn525iBKcOLbcdjEvO+RxiFOBgVOLhTXC7 FCnEmlhWXJl7iFGCg1lJhPdV1eVIId6UxMqq1KL8+KLSnNTiQ4zSHCxK4rx1265FCAmkJ5ak ZqemFqQWwWSZODilGhg3KAtnfVfV33Bs/3O2veUmmfNS5OslpUNe8DmKPtwWMzl56fz/Gh5p OU1t2z8ueS4T96SRL2vuw4AtlesvXy9y8ZlUlHrl25KZi241fGSIadZn31m97VPMRbYL8rNK 4g+xLAt7q3P2xmL3oJO3rPsqr3MqP/3t+Szja+SzR7wtyxYvdsyPfXVYiaU4I9FQi7moOBEA GEHbuRkDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrMLMWRmVeSWpSXmKPExsVy+t9jAd3T9ZcjDVaft7ZY0pRhMed8C4vF v1MbmS2O7XjEZHF51xw2iycLzzBZvPn9gt3i0+2DzBbTTt1hdeD0WDNvDaPHlpU3mTx2zrrL 7rFgU6nH/7NRHju/N7B79E3/wOzxeZNcAEcUl01Kak5mWWqRvl0CV8b0uQeYC97oVPT9Pcza wLhNuYuRk0NCwETi0bYjrF2MXBxCAjsZJR5/bWaEcL4yShxb/pUdpIpNwEpiYvsqRhBbREBb Yt2BHrAOZoF1TBLbp7WzgiSEBVwlps8+yARiswioSuw/tAmsgVdAU2LJ610sILaogJfEln3t TBBxQYkfk++BxZkF5CX27Z/KCmFrSazfeZxpAiPvLCRls5CUzUJStoCReRWjZGpBcW56brFR gVFearlecWJucWleul5yfu4mRmBQbzus1b+D8fGS+EOMAhyMSjy8OzwuRQqxJpYVV+YeYpTg YFYS4X1VdTlSiDclsbIqtSg/vqg0J7X4EKM0B4uSOC9//rFIIYH0xJLU7NTUgtQimCwTB6dU A+Np+erdrcyHJ0dOOsDk/VqOZavxocu3F5XF62z/tOxBVMQzBRu3at6Dy756nrAXboouOzZ/ 1tWj14qS77tM5PZfv0plpXvBfJVHM2aY39l8sco+7tyrBd7yF++JNAr9zk5V3h50ROmzhenc houPs7mKpxqcW8o4a0fQ5OiMp/ue+EypsFZsqN+sxFKckWioxVxUnAgAFaGrAWYCAAA= X-CMS-MailID: 20171003121716epcas2p293688077d6d66b6393f029981adb6108 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: 20171003121716epcas2p293688077d6d66b6393f029981adb6108 X-RootMTR: 20171003121716epcas2p293688077d6d66b6393f029981adb6108 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 Tested-by: Guenter Roeck --- 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). v2: - Added missing 'goto out;' in ide_setup_pci_controller() drivers/ide/setup-pci.c | 63 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 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 14:13:02.391779813 +0200 +++ b/drivers/ide/setup-pci.c 2017-10-03 14:13:59.051779867 +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,20 @@ 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)); } + goto out; + +out_free_bars: + pci_release_selected_regions(dev, bars); out: return ret; } @@ -540,13 +535,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 +564,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 +586,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 +599,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; }