[RFC PATCH 06/10] s390/pci: CHSC PCI support for error and availability events

2012-11-14 Thread Jan Glauber
Add CHSC store-event-information support for PCI (notfication type 2)
and report error and availability events to the PCI architecture layer.

Signed-off-by: Jan Glauber 
---
 arch/s390/include/asm/pci.h |   4 ++
 arch/s390/pci/Makefile  |   3 +-
 arch/s390/pci/pci_event.c   |  93 ++
 drivers/s390/cio/chsc.c | 156 +++-
 4 files changed, 211 insertions(+), 45 deletions(-)
 create mode 100644 arch/s390/pci/pci_event.c

diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index ca48caf..3dc2cb6 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -127,6 +127,10 @@ void zpci_teardown_msi_irq(struct zpci_dev *, struct 
msi_desc *);
 int zpci_msihash_init(void);
 void zpci_msihash_exit(void);
 
+/* Error handling and recovery */
+void zpci_event_error(void *);
+void zpci_event_availability(void *);
+
 /* Helpers */
 struct zpci_dev *get_zdev(struct pci_dev *);
 struct zpci_dev *get_zdev_by_fid(u32);
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index 4590596..7e36f42 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the s390 PCI subsystem.
 #
 
-obj-$(CONFIG_PCI)  += pci.o pci_dma.o pci_clp.o pci_msi.o
+obj-$(CONFIG_PCI)  += pci.o pci_dma.o pci_clp.o pci_msi.o \
+  pci_event.o
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
new file mode 100644
index 000..dbed8cd
--- /dev/null
+++ b/arch/s390/pci/pci_event.c
@@ -0,0 +1,93 @@
+/*
+ *  Copyright IBM Corp. 2012
+ *
+ *  Author(s):
+ *Jan Glauber 
+ */
+
+#define COMPONENT "zPCI"
+#define pr_fmt(fmt) COMPONENT ": " fmt
+
+#include 
+#include 
+
+/* Content Code Description for PCI Function Error */
+struct zpci_ccdf_err {
+   u32 reserved1;
+   u32 fh; /* function handle */
+   u32 fid;/* function id */
+   u32 ett :  4;   /* expected table type */
+   u32 mvn : 12;   /* MSI vector number */
+   u32 dmaas   :  8;   /* DMA address space */
+   u32 :  6;
+   u32 q   :  1;   /* event qualifier */
+   u32 rw  :  1;   /* read/write */
+   u64 faddr;  /* failing address */
+   u32 reserved3;
+   u16 reserved4;
+   u16 pec;/* PCI event code */
+} __packed;
+
+/* Content Code Description for PCI Function Availability */
+struct zpci_ccdf_avail {
+   u32 reserved1;
+   u32 fh; /* function handle */
+   u32 fid;/* function id */
+   u32 reserved2;
+   u32 reserved3;
+   u32 reserved4;
+   u32 reserved5;
+   u16 reserved6;
+   u16 pec;/* PCI event code */
+} __packed;
+
+static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
+{
+   struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+
+   dev_err(>pdev->dev, "event code: 0x%x\n", ccdf->pec);
+}
+
+static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
+{
+   struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+
+   pr_err("%s%s: availability event: fh: 0x%x  fid: 0x%x  event code: 0x%x 
 reason:",
+   (zdev) ? dev_driver_string(>pdev->dev) : "?",
+   (zdev) ? dev_name(>pdev->dev) : "?",
+   ccdf->fh, ccdf->fid, ccdf->pec);
+   print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET,
+  16, 1, ccdf, sizeof(*ccdf), false);
+
+   switch (ccdf->pec) {
+   case 0x0301:
+   zpci_enable_device(zdev);
+   break;
+   case 0x0302:
+   clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
+   break;
+   case 0x0306:
+   clp_find_pci_devices();
+   break;
+   default:
+   break;
+   }
+}
+
+void zpci_event_error(void *data)
+{
+   struct zpci_ccdf_err *ccdf = data;
+   struct zpci_dev *zdev;
+
+   zpci_event_log_err(ccdf);
+   zdev = get_zdev_by_fid(ccdf->fid);
+   if (!zdev) {
+   pr_err("Error event for unknown fid: %x", ccdf->fid);
+   return;
+   }
+}
+
+void zpci_event_availability(void *data)
+{
+   zpci_event_log_avail(data);
+}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 4d51a7c..68e80e2 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,7 @@
 /*
  *   S/390 common I/O routines -- channel subsystem call
  *
- *Copyright IBM Corp. 1999, 2010
+ *Copyright IBM Corp. 1999,2012
  *Author(s): Ingo Adlung (adl...@de.ibm.com)
  *  Cornelia Huck (cornelia.h...@de.ibm.com)
  *  Arnd Bergmann (ar...@de.ibm.com)
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -260,26 +261,45 @@ __get_chpid_from_lir(void *data)

[RFC PATCH 06/10] s390/pci: CHSC PCI support for error and availability events

2012-11-14 Thread Jan Glauber
Add CHSC store-event-information support for PCI (notfication type 2)
and report error and availability events to the PCI architecture layer.

Signed-off-by: Jan Glauber j...@linux.vnet.ibm.com
---
 arch/s390/include/asm/pci.h |   4 ++
 arch/s390/pci/Makefile  |   3 +-
 arch/s390/pci/pci_event.c   |  93 ++
 drivers/s390/cio/chsc.c | 156 +++-
 4 files changed, 211 insertions(+), 45 deletions(-)
 create mode 100644 arch/s390/pci/pci_event.c

diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index ca48caf..3dc2cb6 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -127,6 +127,10 @@ void zpci_teardown_msi_irq(struct zpci_dev *, struct 
msi_desc *);
 int zpci_msihash_init(void);
 void zpci_msihash_exit(void);
 
+/* Error handling and recovery */
+void zpci_event_error(void *);
+void zpci_event_availability(void *);
+
 /* Helpers */
 struct zpci_dev *get_zdev(struct pci_dev *);
 struct zpci_dev *get_zdev_by_fid(u32);
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index 4590596..7e36f42 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the s390 PCI subsystem.
 #
 
-obj-$(CONFIG_PCI)  += pci.o pci_dma.o pci_clp.o pci_msi.o
+obj-$(CONFIG_PCI)  += pci.o pci_dma.o pci_clp.o pci_msi.o \
+  pci_event.o
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
new file mode 100644
index 000..dbed8cd
--- /dev/null
+++ b/arch/s390/pci/pci_event.c
@@ -0,0 +1,93 @@
+/*
+ *  Copyright IBM Corp. 2012
+ *
+ *  Author(s):
+ *Jan Glauber j...@linux.vnet.ibm.com
+ */
+
+#define COMPONENT zPCI
+#define pr_fmt(fmt) COMPONENT :  fmt
+
+#include linux/kernel.h
+#include linux/pci.h
+
+/* Content Code Description for PCI Function Error */
+struct zpci_ccdf_err {
+   u32 reserved1;
+   u32 fh; /* function handle */
+   u32 fid;/* function id */
+   u32 ett :  4;   /* expected table type */
+   u32 mvn : 12;   /* MSI vector number */
+   u32 dmaas   :  8;   /* DMA address space */
+   u32 :  6;
+   u32 q   :  1;   /* event qualifier */
+   u32 rw  :  1;   /* read/write */
+   u64 faddr;  /* failing address */
+   u32 reserved3;
+   u16 reserved4;
+   u16 pec;/* PCI event code */
+} __packed;
+
+/* Content Code Description for PCI Function Availability */
+struct zpci_ccdf_avail {
+   u32 reserved1;
+   u32 fh; /* function handle */
+   u32 fid;/* function id */
+   u32 reserved2;
+   u32 reserved3;
+   u32 reserved4;
+   u32 reserved5;
+   u16 reserved6;
+   u16 pec;/* PCI event code */
+} __packed;
+
+static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
+{
+   struct zpci_dev *zdev = get_zdev_by_fid(ccdf-fid);
+
+   dev_err(zdev-pdev-dev, event code: 0x%x\n, ccdf-pec);
+}
+
+static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
+{
+   struct zpci_dev *zdev = get_zdev_by_fid(ccdf-fid);
+
+   pr_err(%s%s: availability event: fh: 0x%x  fid: 0x%x  event code: 0x%x 
 reason:,
+   (zdev) ? dev_driver_string(zdev-pdev-dev) : ?,
+   (zdev) ? dev_name(zdev-pdev-dev) : ?,
+   ccdf-fh, ccdf-fid, ccdf-pec);
+   print_hex_dump(KERN_CONT, ccdf, DUMP_PREFIX_OFFSET,
+  16, 1, ccdf, sizeof(*ccdf), false);
+
+   switch (ccdf-pec) {
+   case 0x0301:
+   zpci_enable_device(zdev);
+   break;
+   case 0x0302:
+   clp_add_pci_device(ccdf-fid, ccdf-fh, 0);
+   break;
+   case 0x0306:
+   clp_find_pci_devices();
+   break;
+   default:
+   break;
+   }
+}
+
+void zpci_event_error(void *data)
+{
+   struct zpci_ccdf_err *ccdf = data;
+   struct zpci_dev *zdev;
+
+   zpci_event_log_err(ccdf);
+   zdev = get_zdev_by_fid(ccdf-fid);
+   if (!zdev) {
+   pr_err(Error event for unknown fid: %x, ccdf-fid);
+   return;
+   }
+}
+
+void zpci_event_availability(void *data)
+{
+   zpci_event_log_avail(data);
+}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 4d51a7c..68e80e2 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,7 @@
 /*
  *   S/390 common I/O routines -- channel subsystem call
  *
- *Copyright IBM Corp. 1999, 2010
+ *Copyright IBM Corp. 1999,2012
  *Author(s): Ingo Adlung (adl...@de.ibm.com)
  *  Cornelia Huck (cornelia.h...@de.ibm.com)
  *  Arnd Bergmann (ar...@de.ibm.com)
@@ -14,6 +14,7 @@
 #include linux/slab.h
 #include linux/init.h
 #include linux/device.h