19e541b3cSShuai Xue /* SPDX-License-Identifier: GPL-2.0 */ 29e541b3cSShuai Xue #undef TRACE_SYSTEM 39e541b3cSShuai Xue #define TRACE_SYSTEM pci 49e541b3cSShuai Xue 59e541b3cSShuai Xue #if !defined(_TRACE_HW_EVENT_PCI_H) || defined(TRACE_HEADER_MULTI_READ) 69e541b3cSShuai Xue #define _TRACE_HW_EVENT_PCI_H 79e541b3cSShuai Xue 8*d4318c1aSShuai Xue #include <uapi/linux/pci_regs.h> 99e541b3cSShuai Xue #include <linux/tracepoint.h> 109e541b3cSShuai Xue 119e541b3cSShuai Xue #define PCI_HOTPLUG_EVENT \ 129e541b3cSShuai Xue EM(PCI_HOTPLUG_LINK_UP, "LINK_UP") \ 139e541b3cSShuai Xue EM(PCI_HOTPLUG_LINK_DOWN, "LINK_DOWN") \ 149e541b3cSShuai Xue EM(PCI_HOTPLUG_CARD_PRESENT, "CARD_PRESENT") \ 159e541b3cSShuai Xue EMe(PCI_HOTPLUG_CARD_NOT_PRESENT, "CARD_NOT_PRESENT") 169e541b3cSShuai Xue 179e541b3cSShuai Xue /* Enums require being exported to userspace, for user tool parsing */ 189e541b3cSShuai Xue #undef EM 199e541b3cSShuai Xue #undef EMe 209e541b3cSShuai Xue #define EM(a, b) TRACE_DEFINE_ENUM(a); 219e541b3cSShuai Xue #define EMe(a, b) TRACE_DEFINE_ENUM(a); 229e541b3cSShuai Xue 239e541b3cSShuai Xue PCI_HOTPLUG_EVENT 249e541b3cSShuai Xue 259e541b3cSShuai Xue /* 269e541b3cSShuai Xue * Now redefine the EM() and EMe() macros to map the enums to the strings 279e541b3cSShuai Xue * that will be printed in the output. 289e541b3cSShuai Xue */ 299e541b3cSShuai Xue #undef EM 309e541b3cSShuai Xue #undef EMe 319e541b3cSShuai Xue #define EM(a, b) {a, b}, 329e541b3cSShuai Xue #define EMe(a, b) {a, b} 339e541b3cSShuai Xue 349e541b3cSShuai Xue /* 359e541b3cSShuai Xue * Note: For generic PCI hotplug events, we pass already-resolved strings 369e541b3cSShuai Xue * (port_name, slot) instead of driver-specific structures like 'struct 379e541b3cSShuai Xue * controller'. This is because different PCI hotplug drivers (pciehp, cpqphp, 389e541b3cSShuai Xue * ibmphp, shpchp) define their own versions of 'struct controller' with 399e541b3cSShuai Xue * different fields and helper functions. Using driver-specific structures would 409e541b3cSShuai Xue * make the tracepoint interface non-generic and cause compatibility issues 419e541b3cSShuai Xue * across different drivers. 429e541b3cSShuai Xue */ 439e541b3cSShuai Xue TRACE_EVENT(pci_hp_event, 449e541b3cSShuai Xue 459e541b3cSShuai Xue TP_PROTO(const char *port_name, 469e541b3cSShuai Xue const char *slot, 479e541b3cSShuai Xue const int event), 489e541b3cSShuai Xue 499e541b3cSShuai Xue TP_ARGS(port_name, slot, event), 509e541b3cSShuai Xue 519e541b3cSShuai Xue TP_STRUCT__entry( 529e541b3cSShuai Xue __string( port_name, port_name ) 539e541b3cSShuai Xue __string( slot, slot ) 549e541b3cSShuai Xue __field( int, event ) 559e541b3cSShuai Xue ), 569e541b3cSShuai Xue 579e541b3cSShuai Xue TP_fast_assign( 589e541b3cSShuai Xue __assign_str(port_name); 599e541b3cSShuai Xue __assign_str(slot); 609e541b3cSShuai Xue __entry->event = event; 619e541b3cSShuai Xue ), 629e541b3cSShuai Xue 639e541b3cSShuai Xue TP_printk("%s slot:%s, event:%s\n", 649e541b3cSShuai Xue __get_str(port_name), 659e541b3cSShuai Xue __get_str(slot), 669e541b3cSShuai Xue __print_symbolic(__entry->event, PCI_HOTPLUG_EVENT) 679e541b3cSShuai Xue ) 689e541b3cSShuai Xue ); 699e541b3cSShuai Xue 70*d4318c1aSShuai Xue #define PCI_EXP_LNKSTA_LINK_STATUS_MASK (PCI_EXP_LNKSTA_LBMS | \ 71*d4318c1aSShuai Xue PCI_EXP_LNKSTA_LABS | \ 72*d4318c1aSShuai Xue PCI_EXP_LNKSTA_LT | \ 73*d4318c1aSShuai Xue PCI_EXP_LNKSTA_DLLLA) 74*d4318c1aSShuai Xue 75*d4318c1aSShuai Xue #define LNKSTA_FLAGS \ 76*d4318c1aSShuai Xue { PCI_EXP_LNKSTA_LT, "LT"}, \ 77*d4318c1aSShuai Xue { PCI_EXP_LNKSTA_DLLLA, "DLLLA"}, \ 78*d4318c1aSShuai Xue { PCI_EXP_LNKSTA_LBMS, "LBMS"}, \ 79*d4318c1aSShuai Xue { PCI_EXP_LNKSTA_LABS, "LABS"} 80*d4318c1aSShuai Xue 81*d4318c1aSShuai Xue TRACE_EVENT(pcie_link_event, 82*d4318c1aSShuai Xue 83*d4318c1aSShuai Xue TP_PROTO(struct pci_bus *bus, 84*d4318c1aSShuai Xue unsigned int reason, 85*d4318c1aSShuai Xue unsigned int width, 86*d4318c1aSShuai Xue unsigned int status 87*d4318c1aSShuai Xue ), 88*d4318c1aSShuai Xue 89*d4318c1aSShuai Xue TP_ARGS(bus, reason, width, status), 90*d4318c1aSShuai Xue 91*d4318c1aSShuai Xue TP_STRUCT__entry( 92*d4318c1aSShuai Xue __string( port_name, pci_name(bus->self)) 93*d4318c1aSShuai Xue __field( unsigned int, type ) 94*d4318c1aSShuai Xue __field( unsigned int, reason ) 95*d4318c1aSShuai Xue __field( unsigned int, cur_bus_speed ) 96*d4318c1aSShuai Xue __field( unsigned int, max_bus_speed ) 97*d4318c1aSShuai Xue __field( unsigned int, width ) 98*d4318c1aSShuai Xue __field( unsigned int, flit_mode ) 99*d4318c1aSShuai Xue __field( unsigned int, link_status ) 100*d4318c1aSShuai Xue ), 101*d4318c1aSShuai Xue 102*d4318c1aSShuai Xue TP_fast_assign( 103*d4318c1aSShuai Xue __assign_str(port_name); 104*d4318c1aSShuai Xue __entry->type = pci_pcie_type(bus->self); 105*d4318c1aSShuai Xue __entry->reason = reason; 106*d4318c1aSShuai Xue __entry->cur_bus_speed = bus->cur_bus_speed; 107*d4318c1aSShuai Xue __entry->max_bus_speed = bus->max_bus_speed; 108*d4318c1aSShuai Xue __entry->width = width; 109*d4318c1aSShuai Xue __entry->flit_mode = bus->flit_mode; 110*d4318c1aSShuai Xue __entry->link_status = status; 111*d4318c1aSShuai Xue ), 112*d4318c1aSShuai Xue 113*d4318c1aSShuai Xue TP_printk("%s type:%d, reason:%d, cur_bus_speed:%d, max_bus_speed:%d, width:%u, flit_mode:%u, status:%s\n", 114*d4318c1aSShuai Xue __get_str(port_name), 115*d4318c1aSShuai Xue __entry->type, 116*d4318c1aSShuai Xue __entry->reason, 117*d4318c1aSShuai Xue __entry->cur_bus_speed, 118*d4318c1aSShuai Xue __entry->max_bus_speed, 119*d4318c1aSShuai Xue __entry->width, 120*d4318c1aSShuai Xue __entry->flit_mode, 121*d4318c1aSShuai Xue __print_flags((unsigned long)__entry->link_status, "|", 122*d4318c1aSShuai Xue LNKSTA_FLAGS) 123*d4318c1aSShuai Xue ) 124*d4318c1aSShuai Xue ); 125*d4318c1aSShuai Xue 1269e541b3cSShuai Xue #endif /* _TRACE_HW_EVENT_PCI_H */ 1279e541b3cSShuai Xue 1289e541b3cSShuai Xue /* This part must be outside protection */ 1299e541b3cSShuai Xue #include <trace/define_trace.h> 130