Skip to content

Commit fc2b52c

Browse files
committed
firewire: cdev: add new event to notify response subaction with time stamp
This commit adds new event to notify event of response 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-9-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent 147e9d3 commit fc2b52c

2 files changed

Lines changed: 64 additions & 10 deletions

File tree

drivers/firewire/uapi-test.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,24 @@ static void structure_layout_event_request3(struct kunit *test)
4545
KUNIT_EXPECT_EQ(test, 56, offsetof(struct fw_cdev_event_request3, data));
4646
}
4747

48+
// Added at v6.5.
49+
static void structure_layout_event_response2(struct kunit *test)
50+
{
51+
KUNIT_EXPECT_EQ(test, 32, sizeof(struct fw_cdev_event_response2));
52+
53+
KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_response2, closure));
54+
KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_response2, type));
55+
KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_response2, rcode));
56+
KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_response2, length));
57+
KUNIT_EXPECT_EQ(test, 20, offsetof(struct fw_cdev_event_response2, request_tstamp));
58+
KUNIT_EXPECT_EQ(test, 24, offsetof(struct fw_cdev_event_response2, response_tstamp));
59+
KUNIT_EXPECT_EQ(test, 32, offsetof(struct fw_cdev_event_response2, data));
60+
}
61+
4862
static struct kunit_case structure_layout_test_cases[] = {
4963
KUNIT_CASE(structure_layout_event_response),
5064
KUNIT_CASE(structure_layout_event_request3),
65+
KUNIT_CASE(structure_layout_event_response2),
5166
{}
5267
};
5368

include/uapi/linux/firewire-cdev.h

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
/* available since kernel version 6.5 */
5050
#define FW_CDEV_EVENT_REQUEST3 0x0a
51+
#define FW_CDEV_EVENT_RESPONSE2 0x0b
5152

5253
/**
5354
* struct fw_cdev_event_common - Common part of all fw_cdev_event_* types
@@ -106,6 +107,29 @@ struct fw_cdev_event_bus_reset {
106107
* @length: Data length, i.e. the response's payload size in bytes
107108
* @data: Payload data, if any
108109
*
110+
* This event is sent instead of &fw_cdev_event_response if the kernel or the client implements
111+
* ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_response2.
112+
*/
113+
struct fw_cdev_event_response {
114+
__u64 closure;
115+
__u32 type;
116+
__u32 rcode;
117+
__u32 length;
118+
__u32 data[];
119+
};
120+
121+
/**
122+
* struct fw_cdev_event_response2 - Sent when a response packet was received
123+
* @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_SEND_REQUEST
124+
* or %FW_CDEV_IOC_SEND_BROADCAST_REQUEST
125+
* or %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl
126+
* @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE
127+
* @rcode: Response code returned by the remote node
128+
* @length: Data length, i.e. the response's payload size in bytes
129+
* @request_tstamp: The time stamp of isochronous cycle at which the request was sent.
130+
* @response_tstamp: The time stamp of isochronous cycle at which the response was sent.
131+
* @data: Payload data, if any
132+
*
109133
* This event is sent when the stack receives a response to an outgoing request
110134
* sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses
111135
* carrying data (read and lock responses) follows immediately and can be
@@ -115,12 +139,25 @@ struct fw_cdev_event_bus_reset {
115139
* involve response packets. This includes unified write transactions,
116140
* broadcast write transactions, and transmission of asynchronous stream
117141
* packets. @rcode indicates success or failure of such transmissions.
142+
*
143+
* The value of @request_tstamp expresses the isochronous cycle at which the request was sent to
144+
* initiate the transaction. The value of @response_tstamp expresses the isochronous cycle at which
145+
* the response arrived to complete the transaction. Each value is unsigned 16 bit integer
146+
* containing three low order bits of second field and all 13 bits of cycle field in format of
147+
* CYCLE_TIMER register.
118148
*/
119-
struct fw_cdev_event_response {
149+
struct fw_cdev_event_response2 {
120150
__u64 closure;
121151
__u32 type;
122152
__u32 rcode;
123153
__u32 length;
154+
__u32 request_tstamp;
155+
__u32 response_tstamp;
156+
/*
157+
* Padding to keep the size of structure as multiples of 8 in various architectures since
158+
* 4 byte alignment is used for 8 byte of object type in System V ABI for i386 architecture.
159+
*/
160+
__u32 padding;
124161
__u32 data[];
125162
};
126163

@@ -421,6 +458,7 @@ struct fw_cdev_event_phy_packet {
421458
* %FW_CDEV_EVENT_PHY_PACKET_RECEIVED
422459
*
423460
* @request3: Valid if @common.type == %FW_CDEV_EVENT_REQUEST3
461+
* @response2: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE2
424462
*
425463
* Convenience union for userspace use. Events could be read(2) into an
426464
* appropriately aligned char buffer and then cast to this union for further
@@ -441,6 +479,7 @@ union fw_cdev_event {
441479
struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */
442480
struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */
443481
struct fw_cdev_event_request3 request3; /* added in 6.5 */
482+
struct fw_cdev_event_response2 response2; /* added in 6.5 */
444483
};
445484

446485
/* available since kernel version 2.6.22 */
@@ -507,6 +546,7 @@ union fw_cdev_event {
507546
* - added %FW_CDEV_IOC_FLUSH_ISO
508547
* 6 (6.5) - added some event for subactions of asynchronous transaction with time stamp
509548
* - %FW_CDEV_EVENT_REQUEST3
549+
* - %FW_CDEV_EVENT_RESPONSE2
510550
*/
511551

512552
/**
@@ -552,11 +592,11 @@ struct fw_cdev_get_info {
552592
* @data: Userspace pointer to payload
553593
* @generation: The bus generation where packet is valid
554594
*
555-
* Send a request to the device. This ioctl implements all outgoing requests.
556-
* Both quadlet and block request specify the payload as a pointer to the data
557-
* in the @data field. Once the transaction completes, the kernel writes an
558-
* &fw_cdev_event_response event back. The @closure field is passed back to
559-
* user space in the response event.
595+
* Send a request to the device. This ioctl implements all outgoing requests. Both quadlet and
596+
* block request specify the payload as a pointer to the data in the @data field. Once the
597+
* transaction completes, the kernel writes either &fw_cdev_event_response event or
598+
* &fw_cdev_event_response event back. The @closure field is passed back to user space in the
599+
* response event.
560600
*/
561601
struct fw_cdev_send_request {
562602
__u32 tcode;
@@ -1039,10 +1079,9 @@ struct fw_cdev_allocate_iso_resource {
10391079
* @generation: The bus generation where packet is valid
10401080
* @speed: Speed to transmit at
10411081
*
1042-
* The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet
1043-
* to every device which is listening to the specified channel. The kernel
1044-
* writes an &fw_cdev_event_response event which indicates success or failure of
1045-
* the transmission.
1082+
* The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet to every device
1083+
* which is listening to the specified channel. The kernel writes either &fw_cdev_event_response
1084+
* event or &fw_cdev_event_response2 event which indicates success or failure of the transmission.
10461085
*/
10471086
struct fw_cdev_send_stream_packet {
10481087
__u32 length;

0 commit comments

Comments
 (0)