From patchwork Wed Nov 20 17:26:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 292837 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D73162C0126 for ; Thu, 21 Nov 2013 04:27:20 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754093Ab3KTR1T (ORCPT ); Wed, 20 Nov 2013 12:27:19 -0500 Received: from mga11.intel.com ([192.55.52.93]:5639 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751346Ab3KTR1T (ORCPT ); Wed, 20 Nov 2013 12:27:19 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 20 Nov 2013 09:27:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.93,738,1378882800"; d="scan'208";a="436764478" Received: from dcgshare.lm.intel.com ([10.232.118.254]) by fmsmga002.fm.intel.com with ESMTP; 20 Nov 2013 09:26:59 -0800 Received: by dcgshare.lm.intel.com (Postfix, from userid 1017) id 4B34BE00F2; Wed, 20 Nov 2013 10:26:59 -0700 (MST) From: Keith Busch To: linux-pci@vger.kernel.org Cc: Keith Busch Subject: [PATCH] PCI: add function reset callback to pci_driver Date: Wed, 20 Nov 2013 10:26:57 -0700 Message-Id: <1384968417-31856-1-git-send-email-keith.busch@intel.com> X-Mailer: git-send-email 1.7.1 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org A user can issue a pci function level reset to a device using sysfs entry /sys/bus/pci/devices/.../reset. A kernel driver handling the pci device probably would like to know that such a reset has occured, so this patch adds a callback in to pci_driver's pci_error_handler. Signed-off-by: Keith Busch --- Assuming this is a good idea, is this the right place to invoke the reset callback, or should it be up the call stack closer to the sysfs reset entry point? Or somewhere else entirely? drivers/pci/pci.c | 6 ++++++ include/linux/pci.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b127fbda..5ee6fc0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3435,6 +3435,12 @@ static int __pci_dev_reset(struct pci_dev *dev, int probe) rc = pci_parent_bus_reset(dev, probe); done: + if (rc != -ENOTTY && !probe) { + struct pci_error_handlers *err_handler = + dev->driver ? dev->driver->err_handler : NULL; + if (err_handler && err_handler->function_reset) + err_handler->function_reset(dev); + } return rc; } diff --git a/include/linux/pci.h b/include/linux/pci.h index 835ec7b..d1f100e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -605,6 +605,9 @@ struct pci_error_handlers { /* PCI slot has been reset */ pci_ers_result_t (*slot_reset)(struct pci_dev *dev); + /* PCI function has been reset */ + pci_ers_result_t (*function_reset)(struct pci_dev *dev); + /* Device driver may resume normal operations */ void (*resume)(struct pci_dev *dev); };