summaryrefslogtreecommitdiffstats
path: root/arch/s390/pci/pci.c
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-11-29 12:55:21 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-30 15:40:47 +0100
commita755a45dd928e05a4fb980d31d4a0dbc49adc562 (patch)
treead7e88579a6a52c06cada11ce59529e3c8888d06 /arch/s390/pci/pci.c
parentcd24834130ac655d15accee6757e0eaeab4ad4ef (diff)
s390/pci: CLP interface
CLP instructions are used to query the firmware about detected PCI functions, the attributes of those functions and to enable or disable a PCI function. The CLP interface is the equivalent to a PCI bus scan. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r--arch/s390/pci/pci.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 0b80ac7e158..70f6c56c8d0 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -29,6 +29,7 @@
#include <asm/facility.h>
#include <asm/pci_insn.h>
+#include <asm/pci_clp.h>
#define DEBUG /* enable pr_debug */
@@ -436,6 +437,20 @@ static void zpci_free_domain(struct zpci_dev *zdev)
spin_unlock(&zpci_domain_lock);
}
+int zpci_enable_device(struct zpci_dev *zdev)
+{
+ int rc;
+
+ rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
+ if (rc)
+ goto out;
+ pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid);
+ return 0;
+out:
+ return rc;
+}
+EXPORT_SYMBOL_GPL(zpci_enable_device);
+
int zpci_create_device(struct zpci_dev *zdev)
{
int rc;
@@ -455,8 +470,15 @@ int zpci_create_device(struct zpci_dev *zdev)
if (zdev->state == ZPCI_FN_STATE_STANDBY)
return 0;
+ rc = zpci_enable_device(zdev);
+ if (rc)
+ goto out_start;
return 0;
+out_start:
+ mutex_lock(&zpci_list_lock);
+ list_del(&zdev->entry);
+ mutex_unlock(&zpci_list_lock);
out_bus:
zpci_free_domain(zdev);
out:
@@ -489,6 +511,7 @@ int zpci_scan_device(struct zpci_dev *zdev)
return 0;
out:
+ clp_disable_fh(zdev);
return -EIO;
}
EXPORT_SYMBOL_GPL(zpci_scan_device);
@@ -547,9 +570,14 @@ static int __init pci_base_init(void)
if (rc)
goto out_mem;
+ rc = clp_find_pci_devices();
+ if (rc)
+ goto out_find;
+
zpci_scan_devices();
return 0;
+out_find:
zpci_mem_exit();
out_mem:
return rc;