xref: /linux/include/trace/events/pci.h (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #undef TRACE_SYSTEM
3 #define TRACE_SYSTEM pci
4 
5 #if !defined(_TRACE_HW_EVENT_PCI_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_HW_EVENT_PCI_H
7 
8 #include <uapi/linux/pci_regs.h>
9 #include <linux/tracepoint.h>
10 
11 #define PCI_HOTPLUG_EVENT						\
12 	EM(PCI_HOTPLUG_LINK_UP,			"LINK_UP")		\
13 	EM(PCI_HOTPLUG_LINK_DOWN,		"LINK_DOWN")		\
14 	EM(PCI_HOTPLUG_CARD_PRESENT,		"CARD_PRESENT")		\
15 	EMe(PCI_HOTPLUG_CARD_NOT_PRESENT,	"CARD_NOT_PRESENT")
16 
17 /* Enums require being exported to userspace, for user tool parsing */
18 #undef EM
19 #undef EMe
20 #define EM(a, b)	TRACE_DEFINE_ENUM(a);
21 #define EMe(a, b)	TRACE_DEFINE_ENUM(a);
22 
23 PCI_HOTPLUG_EVENT
24 
25 /*
26  * Now redefine the EM() and EMe() macros to map the enums to the strings
27  * that will be printed in the output.
28  */
29 #undef EM
30 #undef EMe
31 #define EM(a, b)	{a, b},
32 #define EMe(a, b)	{a, b}
33 
34 /*
35  * Note: For generic PCI hotplug events, we pass already-resolved strings
36  * (port_name, slot) instead of driver-specific structures like 'struct
37  * controller'.  This is because different PCI hotplug drivers (pciehp, cpqphp,
38  * ibmphp, shpchp) define their own versions of 'struct controller' with
39  * different fields and helper functions. Using driver-specific structures would
40  * make the tracepoint interface non-generic and cause compatibility issues
41  * across different drivers.
42  */
43 TRACE_EVENT(pci_hp_event,
44 
45 	TP_PROTO(const char *port_name,
46 		 const char *slot,
47 		 const int event),
48 
49 	TP_ARGS(port_name, slot, event),
50 
51 	TP_STRUCT__entry(
52 		__string(	port_name,	port_name	)
53 		__string(	slot,		slot		)
54 		__field(	int,		event	)
55 	),
56 
57 	TP_fast_assign(
58 		__assign_str(port_name);
59 		__assign_str(slot);
60 		__entry->event = event;
61 	),
62 
63 	TP_printk("%s slot:%s, event:%s\n",
64 		__get_str(port_name),
65 		__get_str(slot),
66 		__print_symbolic(__entry->event, PCI_HOTPLUG_EVENT)
67 	)
68 );
69 
70 #define PCI_EXP_LNKSTA_LINK_STATUS_MASK (PCI_EXP_LNKSTA_LBMS | \
71 					 PCI_EXP_LNKSTA_LABS | \
72 					 PCI_EXP_LNKSTA_LT | \
73 					 PCI_EXP_LNKSTA_DLLLA)
74 
75 #define LNKSTA_FLAGS					\
76 	{ PCI_EXP_LNKSTA_LT,	"LT"},			\
77 	{ PCI_EXP_LNKSTA_DLLLA,	"DLLLA"},		\
78 	{ PCI_EXP_LNKSTA_LBMS,	"LBMS"},		\
79 	{ PCI_EXP_LNKSTA_LABS,	"LABS"}
80 
81 TRACE_EVENT(pcie_link_event,
82 
83 	TP_PROTO(struct pci_bus *bus,
84 		  unsigned int reason,
85 		  unsigned int width,
86 		  unsigned int status
87 		),
88 
89 	TP_ARGS(bus, reason, width, status),
90 
91 	TP_STRUCT__entry(
92 		__string(	port_name,	pci_name(bus->self))
93 		__field(	unsigned int,	type		)
94 		__field(	unsigned int,	reason		)
95 		__field(	unsigned int,	cur_bus_speed	)
96 		__field(	unsigned int,	max_bus_speed	)
97 		__field(	unsigned int,	width		)
98 		__field(	unsigned int,	flit_mode	)
99 		__field(	unsigned int,	link_status	)
100 	),
101 
102 	TP_fast_assign(
103 		__assign_str(port_name);
104 		__entry->type			= pci_pcie_type(bus->self);
105 		__entry->reason			= reason;
106 		__entry->cur_bus_speed		= bus->cur_bus_speed;
107 		__entry->max_bus_speed		= bus->max_bus_speed;
108 		__entry->width			= width;
109 		__entry->flit_mode		= bus->flit_mode;
110 		__entry->link_status		= status;
111 	),
112 
113 	TP_printk("%s type:%d, reason:%d, cur_bus_speed:%d, max_bus_speed:%d, width:%u, flit_mode:%u, status:%s\n",
114 		__get_str(port_name),
115 		__entry->type,
116 		__entry->reason,
117 		__entry->cur_bus_speed,
118 		__entry->max_bus_speed,
119 		__entry->width,
120 		__entry->flit_mode,
121 		__print_flags((unsigned long)__entry->link_status, "|",
122 				LNKSTA_FLAGS)
123 	)
124 );
125 
126 #endif /* _TRACE_HW_EVENT_PCI_H */
127 
128 /* This part must be outside protection */
129 #include <trace/define_trace.h>
130