diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-14 18:57:22 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-14 18:57:22 -0700 |
commit | b850dc206a57ae272c639e31ac202ec0c2f46960 (patch) | |
tree | 492cc1be0c2923151ca6390aa600200fa4daef1f /include | |
parent | 4f8b6f25eb1e51febd426da764a0b0ea652ad238 (diff) | |
parent | 21151fd8f0ea5dcff27e8db25b65bf892d408bdc (diff) |
Merge tag 'firewire-updates-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394
Pull firewire updates from Takashi Sakamoto:
"During the development period of v6.8 kernel, it became evident that
there was a lack of helper utilities to trace the initial state of
bus, while investigating certain PHYs compliant with different
versions of IEEE 1394 specification.
This series of changes includes the addition of tracepoints events,
provided by 'firewire' subsystem. These events enable tracing of how
firewire core functions during bus reset and asynchronous
communication over IEEE 1394 bus.
When implementing the tracepoints events, it was found that the
existing serialization and deserialization helpers for several types
of asynchronous packets are scattered across both firewire-core and
firewire-ohci kernel modules. A set of inline functions is newly added
to address it, along with some KUnit tests, serving as the foundation
for the tracepoints events. This renders the dispersed code obsolete.
The remaining changes constitute the final steps in phasing out the
usage of deprecated PCI MSI APIs, in continuation from the previous
version"
* tag 'firewire-updates-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: (29 commits)
firewire: obsolete usage of *-objs in Makefile for KUnit test
firewire: core: remove flag and width from u64 formats of tracepoints events
firewire: core: fix type of timestamp for async_inbound_template tracepoints events
firewire: core: add tracepoint event for handling bus reset
Revert "firewire: core: option to log bus reset initiation"
firewire: core: add tracepoints events for initiating bus reset
firewire: ohci: obsolete OHCI_PARAM_DEBUG_BUSRESETS from debug module parameter
firewire: ohci: add bus-reset event for initial set of handled irq
firewire: core: add tracepoints event for asynchronous inbound phy packet
firewire: core/cdev: add tracepoints events for asynchronous phy packet
firewire: core: add tracepoints events for asynchronous outbound response
firewire: core: add tracepoint event for asynchronous inbound request
firewire: core: add tracepoints event for asynchronous inbound response
firewire: core: add tracepoints events for asynchronous outbound request
firewire: core: add support for Linux kernel tracepoints
firewire: core: replace local macros with common inline functions for isochronous packet header
firewire: core: add common macro to serialize/deserialize isochronous packet header
firewire: core: obsolete tcode check macros with inline functions
firewire: ohci: replace hard-coded values with common macros
firewire: ohci: replace hard-coded values with inline functions for asynchronous packet header
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/firewire.h | 3 | ||||
-rw-r--r-- | include/trace/events/firewire.h | 348 |
2 files changed, 350 insertions, 1 deletions
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index dd9f2d765e68..00abe0e5d602 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -463,7 +463,8 @@ struct fw_iso_packet { u32 tag:2; /* tx: Tag in packet header */ u32 sy:4; /* tx: Sy in packet header */ u32 header_length:8; /* Length of immediate header */ - u32 header[]; /* tx: Top of 1394 isoch. data_block */ + /* tx: Top of 1394 isoch. data_block */ + u32 header[] __counted_by(header_length); }; #define FW_ISO_CONTEXT_TRANSMIT 0 diff --git a/include/trace/events/firewire.h b/include/trace/events/firewire.h new file mode 100644 index 000000000000..d695a560673f --- /dev/null +++ b/include/trace/events/firewire.h @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (c) 2024 Takashi Sakamoto + +#define TRACE_SYSTEM firewire + +#if !defined(_FIREWIRE_TRACE_EVENT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _FIREWIRE_TRACE_EVENT_H + +#include <linux/tracepoint.h> +#include <linux/firewire.h> + +#include <linux/firewire-constants.h> + +#include "../../../drivers/firewire/packet-header-definitions.h" + +// The content of TP_printk field is preprocessed, then put to the module binary. +#define ASYNC_HEADER_GET_DESTINATION(header) \ + (((header)[0] & ASYNC_HEADER_Q0_DESTINATION_MASK) >> ASYNC_HEADER_Q0_DESTINATION_SHIFT) + +#define ASYNC_HEADER_GET_TLABEL(header) \ + (((header)[0] & ASYNC_HEADER_Q0_TLABEL_MASK) >> ASYNC_HEADER_Q0_TLABEL_SHIFT) + +#define ASYNC_HEADER_GET_TCODE(header) \ + (((header)[0] & ASYNC_HEADER_Q0_TCODE_MASK) >> ASYNC_HEADER_Q0_TCODE_SHIFT) + +#define ASYNC_HEADER_GET_SOURCE(header) \ + (((header)[1] & ASYNC_HEADER_Q1_SOURCE_MASK) >> ASYNC_HEADER_Q1_SOURCE_SHIFT) + +#define ASYNC_HEADER_GET_OFFSET(header) \ + ((((unsigned long long)((header)[1] & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK)) >> ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT) << 32)| \ + (header)[2] + +#define ASYNC_HEADER_GET_RCODE(header) \ + (((header)[1] & ASYNC_HEADER_Q1_RCODE_MASK) >> ASYNC_HEADER_Q1_RCODE_SHIFT) + +#define QUADLET_SIZE 4 + +DECLARE_EVENT_CLASS(async_outbound_initiate_template, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, header, data, data_count), + TP_STRUCT__entry( + __field(u64, transaction) + __field(u8, generation) + __field(u8, scode) + __array(u32, header, ASYNC_HEADER_QUADLET_COUNT) + __dynamic_array(u32, data, data_count) + ), + TP_fast_assign( + __entry->transaction = transaction; + __entry->generation = generation; + __entry->scode = scode; + memcpy(__entry->header, header, QUADLET_SIZE * ASYNC_HEADER_QUADLET_COUNT); + memcpy(__get_dynamic_array(data), data, __get_dynamic_array_len(data)); + ), + // This format is for the request subaction. + TP_printk( + "transaction=0x%llx generation=%u scode=%u dst_id=0x%04x tlabel=%u tcode=%u src_id=0x%04x offset=0x%012llx header=%s data=%s", + __entry->transaction, + __entry->generation, + __entry->scode, + ASYNC_HEADER_GET_DESTINATION(__entry->header), + ASYNC_HEADER_GET_TLABEL(__entry->header), + ASYNC_HEADER_GET_TCODE(__entry->header), + ASYNC_HEADER_GET_SOURCE(__entry->header), + ASYNC_HEADER_GET_OFFSET(__entry->header), + __print_array(__entry->header, ASYNC_HEADER_QUADLET_COUNT, QUADLET_SIZE), + __print_array(__get_dynamic_array(data), + __get_dynamic_array_len(data) / QUADLET_SIZE, QUADLET_SIZE) + ) +); + +// The value of status is one of ack codes and rcodes specific to Linux FireWire subsystem. +DECLARE_EVENT_CLASS(async_outbound_complete_template, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp), + TP_ARGS(transaction, generation, scode, status, timestamp), + TP_STRUCT__entry( + __field(u64, transaction) + __field(u8, generation) + __field(u8, scode) + __field(u8, status) + __field(u16, timestamp) + ), + TP_fast_assign( + __entry->transaction = transaction; + __entry->generation = generation; + __entry->scode = scode; + __entry->status = status; + __entry->timestamp = timestamp; + ), + TP_printk( + "transaction=0x%llx generation=%u scode=%u status=%u timestamp=0x%04x", + __entry->transaction, + __entry->generation, + __entry->scode, + __entry->status, + __entry->timestamp + ) +); + +// The value of status is one of ack codes and rcodes specific to Linux FireWire subsystem. +DECLARE_EVENT_CLASS(async_inbound_template, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, status, timestamp, header, data, data_count), + TP_STRUCT__entry( + __field(u64, transaction) + __field(u8, generation) + __field(u8, scode) + __field(u8, status) + __field(u16, timestamp) + __array(u32, header, ASYNC_HEADER_QUADLET_COUNT) + __dynamic_array(u32, data, data_count) + ), + TP_fast_assign( + __entry->transaction = transaction; + __entry->generation = generation; + __entry->scode = scode; + __entry->status = status; + __entry->timestamp = timestamp; + memcpy(__entry->header, header, QUADLET_SIZE * ASYNC_HEADER_QUADLET_COUNT); + memcpy(__get_dynamic_array(data), data, __get_dynamic_array_len(data)); + ), + // This format is for the response subaction. + TP_printk( + "transaction=0x%llx generation=%u scode=%u status=%u timestamp=0x%04x dst_id=0x%04x tlabel=%u tcode=%u src_id=0x%04x rcode=%u header=%s data=%s", + __entry->transaction, + __entry->generation, + __entry->scode, + __entry->status, + __entry->timestamp, + ASYNC_HEADER_GET_DESTINATION(__entry->header), + ASYNC_HEADER_GET_TLABEL(__entry->header), + ASYNC_HEADER_GET_TCODE(__entry->header), + ASYNC_HEADER_GET_SOURCE(__entry->header), + ASYNC_HEADER_GET_RCODE(__entry->header), + __print_array(__entry->header, ASYNC_HEADER_QUADLET_COUNT, QUADLET_SIZE), + __print_array(__get_dynamic_array(data), + __get_dynamic_array_len(data) / QUADLET_SIZE, QUADLET_SIZE) + ) +); + +DEFINE_EVENT(async_outbound_initiate_template, async_request_outbound_initiate, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, header, data, data_count) +); + +DEFINE_EVENT(async_outbound_complete_template, async_request_outbound_complete, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp), + TP_ARGS(transaction, generation, scode, status, timestamp) +); + +DEFINE_EVENT(async_inbound_template, async_response_inbound, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, status, timestamp, header, data, data_count) +); + +DEFINE_EVENT_PRINT(async_inbound_template, async_request_inbound, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, status, timestamp, header, data, data_count), + TP_printk( + "transaction=0x%llx generation=%u scode=%u status=%u timestamp=0x%04x dst_id=0x%04x tlabel=%u tcode=%u src_id=0x%04x offset=0x%012llx header=%s data=%s", + __entry->transaction, + __entry->generation, + __entry->scode, + __entry->status, + __entry->timestamp, + ASYNC_HEADER_GET_DESTINATION(__entry->header), + ASYNC_HEADER_GET_TLABEL(__entry->header), + ASYNC_HEADER_GET_TCODE(__entry->header), + ASYNC_HEADER_GET_SOURCE(__entry->header), + ASYNC_HEADER_GET_OFFSET(__entry->header), + __print_array(__entry->header, ASYNC_HEADER_QUADLET_COUNT, QUADLET_SIZE), + __print_array(__get_dynamic_array(data), + __get_dynamic_array_len(data) / QUADLET_SIZE, QUADLET_SIZE) + ) +); + +DEFINE_EVENT_PRINT(async_outbound_initiate_template, async_response_outbound_initiate, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, const u32 *header, const u32 *data, unsigned int data_count), + TP_ARGS(transaction, generation, scode, header, data, data_count), + TP_printk( + "transaction=0x%llx generation=%u scode=%u dst_id=0x%04x tlabel=%u tcode=%u src_id=0x%04x rcode=%u header=%s data=%s", + __entry->transaction, + __entry->generation, + __entry->scode, + ASYNC_HEADER_GET_DESTINATION(__entry->header), + ASYNC_HEADER_GET_TLABEL(__entry->header), + ASYNC_HEADER_GET_TCODE(__entry->header), + ASYNC_HEADER_GET_SOURCE(__entry->header), + ASYNC_HEADER_GET_RCODE(__entry->header), + __print_array(__entry->header, ASYNC_HEADER_QUADLET_COUNT, QUADLET_SIZE), + __print_array(__get_dynamic_array(data), + __get_dynamic_array_len(data) / QUADLET_SIZE, QUADLET_SIZE) + ) +); + +DEFINE_EVENT(async_outbound_complete_template, async_response_outbound_complete, + TP_PROTO(u64 transaction, unsigned int generation, unsigned int scode, unsigned int status, unsigned int timestamp), + TP_ARGS(transaction, generation, scode, status, timestamp) +); + +#undef ASYNC_HEADER_GET_DESTINATION +#undef ASYNC_HEADER_GET_TLABEL +#undef ASYNC_HEADER_GET_TCODE +#undef ASYNC_HEADER_GET_SOURCE +#undef ASYNC_HEADER_GET_OFFSET +#undef ASYNC_HEADER_GET_RCODE + +TRACE_EVENT(async_phy_outbound_initiate, + TP_PROTO(u64 packet, unsigned int generation, u32 first_quadlet, u32 second_quadlet), + TP_ARGS(packet, generation, first_quadlet, second_quadlet), + TP_STRUCT__entry( + __field(u64, packet) + __field(u8, generation) + __field(u32, first_quadlet) + __field(u32, second_quadlet) + ), + TP_fast_assign( + __entry->packet = packet; + __entry->generation = generation; + __entry->first_quadlet = first_quadlet; + __entry->second_quadlet = second_quadlet + ), + TP_printk( + "packet=0x%llx generation=%u first_quadlet=0x%08x second_quadlet=0x%08x", + __entry->packet, + __entry->generation, + __entry->first_quadlet, + __entry->second_quadlet + ) +); + +TRACE_EVENT(async_phy_outbound_complete, + TP_PROTO(u64 packet, unsigned int generation, unsigned int status, unsigned int timestamp), + TP_ARGS(packet, generation, status, timestamp), + TP_STRUCT__entry( + __field(u64, packet) + __field(u8, generation) + __field(u8, status) + __field(u16, timestamp) + ), + TP_fast_assign( + __entry->packet = packet; + __entry->generation = generation; + __entry->status = status; + __entry->timestamp = timestamp; + ), + TP_printk( + "packet=0x%llx generation=%u status=%u timestamp=0x%04x", + __entry->packet, + __entry->generation, + __entry->status, + __entry->timestamp + ) +); + +TRACE_EVENT(async_phy_inbound, + TP_PROTO(u64 packet, unsigned int generation, unsigned int status, unsigned int timestamp, u32 first_quadlet, u32 second_quadlet), + TP_ARGS(packet, generation, status, timestamp, first_quadlet, second_quadlet), + TP_STRUCT__entry( + __field(u64, packet) + __field(u8, generation) + __field(u8, status) + __field(u16, timestamp) + __field(u32, first_quadlet) + __field(u32, second_quadlet) + ), + TP_fast_assign( + __entry->packet = packet; + __entry->generation = generation; + __entry->status = status; + __entry->timestamp = timestamp; + __entry->first_quadlet = first_quadlet; + __entry->second_quadlet = second_quadlet + ), + TP_printk( + "packet=0x%llx generation=%u status=%u timestamp=0x%04x first_quadlet=0x%08x second_quadlet=0x%08x", + __entry->packet, + __entry->generation, + __entry->status, + __entry->timestamp, + __entry->first_quadlet, + __entry->second_quadlet + ) +); + +DECLARE_EVENT_CLASS(bus_reset_arrange_template, + TP_PROTO(unsigned int generation, bool short_reset), + TP_ARGS(generation, short_reset), + TP_STRUCT__entry( + __field(u8, generation) + __field(bool, short_reset) + ), + TP_fast_assign( + __entry->generation = generation; + __entry->short_reset = short_reset; + ), + TP_printk( + "generation=%u short_reset=%s", + __entry->generation, + __entry->short_reset ? "true" : "false" + ) +); + +DEFINE_EVENT(bus_reset_arrange_template, bus_reset_initiate, + TP_PROTO(unsigned int generation, bool short_reset), + TP_ARGS(generation, short_reset) +); + +DEFINE_EVENT(bus_reset_arrange_template, bus_reset_schedule, + TP_PROTO(unsigned int generation, bool short_reset), + TP_ARGS(generation, short_reset) +); + +DEFINE_EVENT(bus_reset_arrange_template, bus_reset_postpone, + TP_PROTO(unsigned int generation, bool short_reset), + TP_ARGS(generation, short_reset) +); + +TRACE_EVENT(bus_reset_handle, + TP_PROTO(unsigned int generation, unsigned int node_id, bool bm_abdicate, u32 *self_ids, unsigned int self_id_count), + TP_ARGS(generation, node_id, bm_abdicate, self_ids, self_id_count), + TP_STRUCT__entry( + __field(u8, generation) + __field(u8, node_id) + __field(bool, bm_abdicate) + __dynamic_array(u32, self_ids, self_id_count) + ), + TP_fast_assign( + __entry->generation = generation; + __entry->node_id = node_id; + __entry->bm_abdicate = bm_abdicate; + memcpy(__get_dynamic_array(self_ids), self_ids, __get_dynamic_array_len(self_ids)); + ), + TP_printk( + "generation=%u node_id=0x%04x bm_abdicate=%s self_ids=%s", + __entry->generation, + __entry->node_id, + __entry->bm_abdicate ? "true" : "false", + __print_array(__get_dynamic_array(self_ids), + __get_dynamic_array_len(self_ids) / QUADLET_SIZE, QUADLET_SIZE) + ) +); + +#undef QUADLET_SIZE + +#endif // _FIREWIRE_TRACE_EVENT_H + +#include <trace/define_trace.h> |