From patchwork Thu Nov 20 22:54:24 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 5351261 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DA5129F1E1 for ; Thu, 20 Nov 2014 22:54:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0A70A201BB for ; Thu, 20 Nov 2014 22:54:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 12CF12016C for ; Thu, 20 Nov 2014 22:54:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756756AbaKTWyL (ORCPT ); Thu, 20 Nov 2014 17:54:11 -0500 Received: from mail-pa0-f49.google.com ([209.85.220.49]:34332 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757222AbaKTWyI (ORCPT ); Thu, 20 Nov 2014 17:54:08 -0500 Received: by mail-pa0-f49.google.com with SMTP id eu11so3440966pac.8 for ; Thu, 20 Nov 2014 14:54:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding; bh=pWG+C7wRL42K6ngxIcPvOJmItJsvfCIICU0LyBfVX6M=; b=bBJof/2TbMrOO+sY/4rP7XB1sholp4psUSxMJPimm+skMLMnNRqzEuGuXMZnxJv+rj ux1O4XLq3fJQMeO7+uvPPHUC0IvwdcwkuI6cu3MSi2EaKM1BFgg7i0aDR9ISK+lJiCuf PuiKalkx9ZJykazTpLM7oWbUCYZg8fDRPK/9AmhIDeshnCLewsjTd6V9Ga1qlg93NcMA 3yq31CSasJyITVwjzc05Tj2Ge5UIyhbWCyqclEWu5jRrPNxzWhYIqz+6wUk9yThBvo1F Wb9gTg+RpxL9/NZXFIV1P697TmO1ZXROo2ilbqdsmnCSs2heOQ0TEmTj5qfs0LpAJ1/S wBag== X-Received: by 10.66.154.10 with SMTP id vk10mr1527907pab.26.1416524048190; Thu, 20 Nov 2014 14:54:08 -0800 (PST) Received: from [192.168.95.133] ([66.129.239.13]) by mx.google.com with ESMTPSA id s7sm2946296pdi.72.2014.11.20.14.54.07 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 20 Nov 2014 14:54:07 -0800 (PST) Message-ID: <546E7120.5080505@gmail.com> Date: Thu, 20 Nov 2014 14:54:24 -0800 From: Rajat Jain User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130803 Thunderbird/17.0.8 MIME-Version: 1.0 To: Bjorn Helgaas , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org CC: Rajat Jain , Guenter Roeck , Rajat Jain Subject: [PATCH v2] PCI: pciehp: Check link state before accessing device during removal Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 removing a card, we can't assume the presence to mean that the access to card is OK. That is because the cause of removal may be a link down event, and the card may still be physically present. Thus, instead of presence, use the link state to decide whether or not it is OK to access the card devices. Here are the problem symptoms: During the removal of a card due to link down, sometimes the following error is seen (because pciehp_unconfigure_device() reads 0xFF from bridge control register as the link is down, which cause it to assume that the VGA bit is set): pciehp 0000:21:05.0:pcie24: pcie_isr: intr_loc 100 pciehp 0000:21:05.0:pcie24: Data Link Layer State change pciehp 0000:21:05.0:pcie24: slot(5): Link Down event pciehp 0000:21:05.0:pcie24: Disabling domain:bus:device=0000:60:00 pciehp 0000:21:05.0:pcie24: pciehp_unconfigure_device: domain:bus:dev = 0000:60:00 pciehp 0000:21:05.0:pcie24: Cannot remove display device 0000:60:00.0 Ofcourse, when the link comes back up, the device addition fails too: pciehp 0000:21:05.0:pcie24: pcie_isr: intr_loc 100 pciehp 0000:21:05.0:pcie24: Data Link Layer State change pciehp 0000:21:05.0:pcie24: pciehp_check_link_active: lnk_status = 6011 pciehp 0000:21:05.0:pcie24: slot(5): Link Up event pciehp 0000:21:05.0:pcie24: Enabling domain:bus:device=0000:60:00 pciehp 0000:21:05.0:pcie24: pciehp_check_link_active: lnk_status = 6011 pciehp 0000:21:05.0:pcie24: pciehp_check_link_status: lnk_status = 6011 pciehp 0000:21:05.0:pcie24: Device 0000:60:00.0 already exists at 0000:60:00, cannot hot-add pciehp 0000:21:05.0:pcie24: Cannot add device at 0000:60:00 The problem is not seen with this patch applied. The device removal and insertion works as expected. Signed-off-by: Rajat Jain Signed-off-by: Rajat Jain Signed-off-by: Guenter Roeck --- v2: Use the already initialized "ctrl" instead of "p_slot->ctrl" drivers/pci/hotplug/pciehp_pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 9e69403..911f85b 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -77,7 +77,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) { int rc = 0; u8 bctl = 0; - u8 presence = 0; + bool link_active = false; struct pci_dev *dev, *temp; struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; u16 command; @@ -85,7 +85,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n", __func__, pci_domain_nr(parent), parent->number); - pciehp_get_adapter_status(p_slot, &presence); + link_active = pciehp_check_link_active(ctrl); pci_lock_rescan_remove(); @@ -98,7 +98,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) list_for_each_entry_safe_reverse(dev, temp, &parent->devices, bus_list) { pci_dev_get(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && link_active) { pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { ctrl_err(ctrl, @@ -114,7 +114,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) * Ensure that no new Requests will be generated from * the device. */ - if (presence) { + if (link_active) { pci_read_config_word(dev, PCI_COMMAND, &command); command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); command |= PCI_COMMAND_INTX_DISABLE;