xref: /openbmc/linux/arch/s390/pci/pci_event.c (revision d0b08853)
1 /*
2  *  Copyright IBM Corp. 2012
3  *
4  *  Author(s):
5  *    Jan Glauber <jang@linux.vnet.ibm.com>
6  */
7 
8 #define COMPONENT "zPCI"
9 #define pr_fmt(fmt) COMPONENT ": " fmt
10 
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 
14 /* Content Code Description for PCI Function Error */
15 struct zpci_ccdf_err {
16 	u32 reserved1;
17 	u32 fh;				/* function handle */
18 	u32 fid;			/* function id */
19 	u32 ett		:  4;		/* expected table type */
20 	u32 mvn		: 12;		/* MSI vector number */
21 	u32 dmaas	:  8;		/* DMA address space */
22 	u32		:  6;
23 	u32 q		:  1;		/* event qualifier */
24 	u32 rw		:  1;		/* read/write */
25 	u64 faddr;			/* failing address */
26 	u32 reserved3;
27 	u16 reserved4;
28 	u16 pec;			/* PCI event code */
29 } __packed;
30 
31 /* Content Code Description for PCI Function Availability */
32 struct zpci_ccdf_avail {
33 	u32 reserved1;
34 	u32 fh;				/* function handle */
35 	u32 fid;			/* function id */
36 	u32 reserved2;
37 	u32 reserved3;
38 	u32 reserved4;
39 	u32 reserved5;
40 	u16 reserved6;
41 	u16 pec;			/* PCI event code */
42 } __packed;
43 
44 static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
45 {
46 	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
47 
48 	zpci_err("SEI error CCD:\n");
49 	zpci_err_hex(ccdf, sizeof(*ccdf));
50 	dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
51 }
52 
53 static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
54 {
55 	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
56 
57 	pr_err("%s%s: availability event: fh: 0x%x  fid: 0x%x  event code: 0x%x  reason:",
58 		(zdev) ? dev_driver_string(&zdev->pdev->dev) : "?",
59 		(zdev) ? dev_name(&zdev->pdev->dev) : "?",
60 		ccdf->fh, ccdf->fid, ccdf->pec);
61 	print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET,
62 		       16, 1, ccdf, sizeof(*ccdf), false);
63 
64 	switch (ccdf->pec) {
65 	case 0x0301:
66 		zpci_enable_device(zdev);
67 		break;
68 	case 0x0302:
69 		clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
70 		break;
71 	case 0x0306:
72 		clp_find_pci_devices();
73 		break;
74 	default:
75 		break;
76 	}
77 }
78 
79 void zpci_event_error(void *data)
80 {
81 	struct zpci_ccdf_err *ccdf = data;
82 	struct zpci_dev *zdev;
83 
84 	zpci_event_log_err(ccdf);
85 	zdev = get_zdev_by_fid(ccdf->fid);
86 	if (!zdev) {
87 		pr_err("Error event for unknown fid: %x", ccdf->fid);
88 		return;
89 	}
90 }
91 
92 void zpci_event_availability(void *data)
93 {
94 	zpci_event_log_avail(data);
95 }
96