Skip to content

Commit 7c22d4a

Browse files
committed
firewire: cdev: add new event to notify request subaction with time stamp
This commit adds new event to notify event of request subaction with time stamp field. Current compiler implementation of System V ABI selects one of structure members which has the maximum alignment size in the structure to decide the size of structure. In the case of fw_cdev_event_request3 structure, it is closure member which has 8 byte storage. The size of alignment for the type of 8 byte storage differs depending on architectures; 4 byte for i386 architecture and 8 byte for the others including x32 architecture. It is inconvenient to device driver developer to use structure layout which varies between architectures since the developer takes care of ioctl compat layer. This commit adds 32 bit member for padding to keep the size of structure as multiples of 8. Cc: kunit-dev@googlegroups.com Link: https://lore.kernel.org/r/20230529113406.986289-4-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent 6add87e commit 7c22d4a

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

drivers/firewire/uapi-test.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,28 @@ static void structure_layout_event_response(struct kunit *test)
2626
KUNIT_EXPECT_EQ(test, 20, offsetof(struct fw_cdev_event_response, data));
2727
}
2828

29+
// Added at v6.5.
30+
static void structure_layout_event_request3(struct kunit *test)
31+
{
32+
KUNIT_EXPECT_EQ(test, 56, sizeof(struct fw_cdev_event_request3));
33+
34+
KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_request3, closure));
35+
KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_request3, type));
36+
KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_request3, tcode));
37+
KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_request3, offset));
38+
KUNIT_EXPECT_EQ(test, 24, offsetof(struct fw_cdev_event_request3, source_node_id));
39+
KUNIT_EXPECT_EQ(test, 28, offsetof(struct fw_cdev_event_request3, destination_node_id));
40+
KUNIT_EXPECT_EQ(test, 32, offsetof(struct fw_cdev_event_request3, card));
41+
KUNIT_EXPECT_EQ(test, 36, offsetof(struct fw_cdev_event_request3, generation));
42+
KUNIT_EXPECT_EQ(test, 40, offsetof(struct fw_cdev_event_request3, handle));
43+
KUNIT_EXPECT_EQ(test, 44, offsetof(struct fw_cdev_event_request3, length));
44+
KUNIT_EXPECT_EQ(test, 48, offsetof(struct fw_cdev_event_request3, tstamp));
45+
KUNIT_EXPECT_EQ(test, 56, offsetof(struct fw_cdev_event_request3, data));
46+
}
47+
2948
static struct kunit_case structure_layout_test_cases[] = {
3049
KUNIT_CASE(structure_layout_event_response),
50+
KUNIT_CASE(structure_layout_event_request3),
3151
{}
3252
};
3353

include/uapi/linux/firewire-cdev.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08
4747
#define FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL 0x09
4848

49+
/* available since kernel version 6.5 */
50+
#define FW_CDEV_EVENT_REQUEST3 0x0a
51+
4952
/**
5053
* struct fw_cdev_event_common - Common part of all fw_cdev_event_* types
5154
* @closure: For arbitrary use by userspace
@@ -159,6 +162,38 @@ struct fw_cdev_event_request {
159162
* @length: Data length, i.e. the request's payload size in bytes
160163
* @data: Incoming data, if any
161164
*
165+
* This event is sent instead of &fw_cdev_event_request3 if the kernel or the client implements
166+
* ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_request3.
167+
*/
168+
struct fw_cdev_event_request2 {
169+
__u64 closure;
170+
__u32 type;
171+
__u32 tcode;
172+
__u64 offset;
173+
__u32 source_node_id;
174+
__u32 destination_node_id;
175+
__u32 card;
176+
__u32 generation;
177+
__u32 handle;
178+
__u32 length;
179+
__u32 data[];
180+
};
181+
182+
/**
183+
* struct fw_cdev_event_request3 - Sent on incoming request to an address region
184+
* @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl
185+
* @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST2
186+
* @tcode: Transaction code of the incoming request
187+
* @offset: The offset into the 48-bit per-node address space
188+
* @source_node_id: Sender node ID
189+
* @destination_node_id: Destination node ID
190+
* @card: The index of the card from which the request came
191+
* @generation: Bus generation in which the request is valid
192+
* @handle: Reference to the kernel-side pending request
193+
* @length: Data length, i.e. the request's payload size in bytes
194+
* @tstamp: The time stamp of isochronous cycle at which the request arrived.
195+
* @data: Incoming data, if any
196+
*
162197
* This event is sent when the stack receives an incoming request to an address
163198
* region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is
164199
* guaranteed to be completely contained in the specified region. Userspace is
@@ -191,10 +226,14 @@ struct fw_cdev_event_request {
191226
* sent.
192227
*
193228
* If the client subsequently needs to initiate requests to the sender node of
194-
* an &fw_cdev_event_request2, it needs to use a device file with matching
229+
* an &fw_cdev_event_request3, it needs to use a device file with matching
195230
* card index, node ID, and generation for outbound requests.
231+
*
232+
* @tstamp is isochronous cycle at which the request arrived. It is 16 bit integer value and the
233+
* higher 3 bits expresses three low order bits of second field in the format of CYCLE_TIME
234+
* register and the rest 13 bits expresses cycle field.
196235
*/
197-
struct fw_cdev_event_request2 {
236+
struct fw_cdev_event_request3 {
198237
__u64 closure;
199238
__u32 type;
200239
__u32 tcode;
@@ -205,6 +244,12 @@ struct fw_cdev_event_request2 {
205244
__u32 generation;
206245
__u32 handle;
207246
__u32 length;
247+
__u32 tstamp;
248+
/*
249+
* Padding to keep the size of structure as multiples of 8 in various architectures since
250+
* 4 byte alignment is used for 8 byte of object type in System V ABI for i386 architecture.
251+
*/
252+
__u32 padding;
208253
__u32 data[];
209254
};
210255

@@ -375,6 +420,8 @@ struct fw_cdev_event_phy_packet {
375420
* %FW_CDEV_EVENT_PHY_PACKET_SENT or
376421
* %FW_CDEV_EVENT_PHY_PACKET_RECEIVED
377422
*
423+
* @request3: Valid if @common.type == %FW_CDEV_EVENT_REQUEST3
424+
*
378425
* Convenience union for userspace use. Events could be read(2) into an
379426
* appropriately aligned char buffer and then cast to this union for further
380427
* processing. Note that for a request, response or iso_interrupt event,
@@ -393,6 +440,7 @@ union fw_cdev_event {
393440
struct fw_cdev_event_iso_interrupt_mc iso_interrupt_mc; /* added in 2.6.36 */
394441
struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */
395442
struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */
443+
struct fw_cdev_event_request3 request3; /* added in 6.5 */
396444
};
397445

398446
/* available since kernel version 2.6.22 */
@@ -458,6 +506,7 @@ union fw_cdev_event {
458506
* avoid dropping data
459507
* - added %FW_CDEV_IOC_FLUSH_ISO
460508
* 6 (6.5) - added some event for subactions of asynchronous transaction with time stamp
509+
* - %FW_CDEV_EVENT_REQUEST3
461510
*/
462511

463512
/**

0 commit comments

Comments
 (0)