From 6add87e9764dd308006b078cbdbf36d5a611cc9b Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:39 +0900 Subject: firewire: cdev: add new version of ABI to notify time stamp at request/response subaction of transaction This commit adds new version of ABI for future new events with time stamp for request/response subaction of asynchronous transaction to user space. Link: https://lore.kernel.org/r/20230529113406.986289-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 2c16ee8fd842..88c8b5fac5e5 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -43,6 +43,7 @@ #define FW_CDEV_VERSION_EVENT_REQUEST2 4 #define FW_CDEV_VERSION_ALLOCATE_REGION_END 4 #define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5 +#define FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP 6 struct client { u32 version; -- cgit v1.2.3 From 865efffb2d11402bc6f96c7e390b89384e9d209d Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:40 +0900 Subject: firewire: cdev: implement new event to notify request subaction with time stamp In 1394 OHCI, the trailer quadlet of descriptor in Asynchronous Receive (AR) request context has timeStamp field, in which the 1394 OHCI controller record the isochronous cycle when the packet arrived. Current implementation of 1394 OHCI controller driver stores the value of field to internal structure as time stamp, while the implementation of FireWire character device doesn't have a field for the time stamp, thus it is not available in user space. The time stamp is convenient to some kind of application in which data from several sources are compared in isochronous cycle unit. This commit implement the new event, fw_cdev_event_request3, with an additional field, tstamp. Link: https://lore.kernel.org/r/20230529113406.986289-5-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 88c8b5fac5e5..5a9446d30447 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -178,6 +178,7 @@ struct inbound_transaction_event { union { struct fw_cdev_event_request request; struct fw_cdev_event_request2 request2; + struct fw_cdev_event_request3 with_tstamp; } req; }; @@ -709,7 +710,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request, req->handle = r->resource.handle; req->closure = handler->closure; event_size0 = sizeof(*req); - } else { + } else if (handler->client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { struct fw_cdev_event_request2 *req = &e->req.request2; req->type = FW_CDEV_EVENT_REQUEST2; @@ -723,6 +724,21 @@ static void handle_request(struct fw_card *card, struct fw_request *request, req->handle = r->resource.handle; req->closure = handler->closure; event_size0 = sizeof(*req); + } else { + struct fw_cdev_event_request3 *req = &e->req.with_tstamp; + + req->type = FW_CDEV_EVENT_REQUEST3; + req->tcode = tcode; + req->offset = offset; + req->source_node_id = source; + req->destination_node_id = destination; + req->card = card->index; + req->generation = generation; + req->length = length; + req->handle = r->resource.handle; + req->closure = handler->closure; + req->tstamp = fw_request_get_timestamp(request); + event_size0 = sizeof(*req); } queue_event(handler->client, &e->event, -- cgit v1.2.3 From 147e9d3af34a92ff567c58b0e89099d26787faba Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:40 +0900 Subject: firewire: cdev: code refactoring to operate event of response This commit is a preparation to handle time stamp of asynchronous transaction for user space application. Link: https://lore.kernel.org/r/20230529113406.986289-8-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 5a9446d30447..315ebc8c545d 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -170,7 +170,9 @@ struct outbound_transaction_event { struct event event; struct client *client; struct outbound_transaction_resource r; - struct fw_cdev_event_response response; + union { + struct fw_cdev_event_response without_tstamp; + } rsp; }; struct inbound_transaction_event { @@ -540,7 +542,7 @@ static void complete_transaction(struct fw_card *card, int rcode, void *payload, size_t length, void *data) { struct outbound_transaction_event *e = data; - struct fw_cdev_event_response *rsp = &e->response; + struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; struct client *client = e->client; unsigned long flags; @@ -581,6 +583,8 @@ static int init_request(struct client *client, int destination_id, int speed) { struct outbound_transaction_event *e; + struct fw_cdev_event_response *rsp; + void *payload; int ret; if (request->tcode != TCODE_STREAM_DATA && @@ -594,14 +598,14 @@ static int init_request(struct client *client, e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL); if (e == NULL) return -ENOMEM; - e->client = client; - e->response.length = request->length; - e->response.closure = request->closure; - if (request->data && - copy_from_user(e->response.data, - u64_to_uptr(request->data), request->length)) { + rsp = &e->rsp.without_tstamp; + rsp->length = request->length; + rsp->closure = request->closure; + payload = rsp->data; + + if (request->data && copy_from_user(payload, u64_to_uptr(request->data), request->length)) { ret = -EFAULT; goto failed; } @@ -611,10 +615,9 @@ static int init_request(struct client *client, if (ret < 0) goto failed; - fw_send_request(client->device->card, &e->r.transaction, - request->tcode, destination_id, request->generation, - speed, request->offset, e->response.data, - request->length, complete_transaction, e); + fw_send_request(client->device->card, &e->r.transaction, request->tcode, destination_id, + request->generation, speed, request->offset, payload, request->length, + complete_transaction, e); return 0; failed: -- cgit v1.2.3 From d8527cab6c311da34193b7c04f4d363fc2d72458 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:40 +0900 Subject: firewire: cdev: implement new event to notify response subaction with time stamp The callback function now receives an argument for time stamps relevant to asynchronous transaction. This commit implements a new event to notify response subaction with the time stamps for user space. Link: https://lore.kernel.org/r/20230529113406.986289-10-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 96 ++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 31 deletions(-) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 315ebc8c545d..8b24abdd51b8 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -172,6 +172,7 @@ struct outbound_transaction_event { struct outbound_transaction_resource r; union { struct fw_cdev_event_response without_tstamp; + struct fw_cdev_event_response2 with_tstamp; } rsp; }; @@ -538,41 +539,64 @@ static void release_transaction(struct client *client, { } -static void complete_transaction(struct fw_card *card, int rcode, - void *payload, size_t length, void *data) +static void complete_transaction(struct fw_card *card, int rcode, u32 request_tstamp, + u32 response_tstamp, void *payload, size_t length, void *data) { struct outbound_transaction_event *e = data; - struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; struct client *client = e->client; unsigned long flags; - if (length < rsp->length) - rsp->length = length; - if (rcode == RCODE_COMPLETE) - memcpy(rsp->data, payload, rsp->length); - spin_lock_irqsave(&client->lock, flags); idr_remove(&client->resource_idr, e->r.resource.handle); if (client->in_shutdown) wake_up(&client->tx_flush_wait); spin_unlock_irqrestore(&client->lock, flags); - rsp->type = FW_CDEV_EVENT_RESPONSE; - rsp->rcode = rcode; + switch (e->rsp.without_tstamp.type) { + case FW_CDEV_EVENT_RESPONSE: + { + struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; + + if (length < rsp->length) + rsp->length = length; + if (rcode == RCODE_COMPLETE) + memcpy(rsp->data, payload, rsp->length); + + rsp->rcode = rcode; + + // In the case that sizeof(*rsp) doesn't align with the position of the + // data, and the read is short, preserve an extra copy of the data + // to stay compatible with a pre-2.6.27 bug. Since the bug is harmless + // for short reads and some apps depended on it, this is both safe + // and prudent for compatibility. + if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data)) + queue_event(client, &e->event, rsp, sizeof(*rsp), rsp->data, rsp->length); + else + queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, NULL, 0); - /* - * In the case that sizeof(*rsp) doesn't align with the position of the - * data, and the read is short, preserve an extra copy of the data - * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless - * for short reads and some apps depended on it, this is both safe - * and prudent for compatibility. - */ - if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data)) - queue_event(client, &e->event, rsp, sizeof(*rsp), - rsp->data, rsp->length); - else - queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, - NULL, 0); + break; + } + case FW_CDEV_EVENT_RESPONSE2: + { + struct fw_cdev_event_response2 *rsp = &e->rsp.with_tstamp; + + if (length < rsp->length) + rsp->length = length; + if (rcode == RCODE_COMPLETE) + memcpy(rsp->data, payload, rsp->length); + + rsp->rcode = rcode; + rsp->request_tstamp = request_tstamp; + rsp->response_tstamp = response_tstamp; + + queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, NULL, 0); + + break; + default: + WARN_ON(1); + break; + } + } /* Drop the idr's reference */ client_put(client); @@ -583,7 +607,6 @@ static int init_request(struct client *client, int destination_id, int speed) { struct outbound_transaction_event *e; - struct fw_cdev_event_response *rsp; void *payload; int ret; @@ -600,10 +623,21 @@ static int init_request(struct client *client, return -ENOMEM; e->client = client; - rsp = &e->rsp.without_tstamp; - rsp->length = request->length; - rsp->closure = request->closure; - payload = rsp->data; + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { + struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; + + rsp->type = FW_CDEV_EVENT_RESPONSE; + rsp->length = request->length; + rsp->closure = request->closure; + payload = rsp->data; + } else { + struct fw_cdev_event_response2 *rsp = &e->rsp.with_tstamp; + + rsp->type = FW_CDEV_EVENT_RESPONSE2; + rsp->length = request->length; + rsp->closure = request->closure; + payload = rsp->data; + } if (request->data && copy_from_user(payload, u64_to_uptr(request->data), request->length)) { ret = -EFAULT; @@ -615,9 +649,9 @@ static int init_request(struct client *client, if (ret < 0) goto failed; - fw_send_request(client->device->card, &e->r.transaction, request->tcode, destination_id, - request->generation, speed, request->offset, payload, request->length, - complete_transaction, e); + fw_send_request_with_tstamp(client->device->card, &e->r.transaction, request->tcode, + destination_id, request->generation, speed, request->offset, + payload, request->length, complete_transaction, e); return 0; failed: -- cgit v1.2.3 From 1ef147710b54d47f4108c802d8ee6f3d27fe922d Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:40 +0900 Subject: firewire: cdev: code refactoring to dispatch event for phy packet In 1394 OHCI, both Asynchronous Transmit (AT) and Asynchronous Receive (AR) contexts are used to deliver the phy packet of IEEE 1394. The time stamp is available as well as the usual asynchronous transaction. This commit is a preparation for future commit to handle the time stamp. Link: https://lore.kernel.org/r/20230529113406.986289-11-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 78 +++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 8b24abdd51b8..2220de3c945e 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -204,12 +204,16 @@ struct outbound_phy_packet_event { struct event event; struct client *client; struct fw_packet p; - struct fw_cdev_event_phy_packet phy_packet; + union { + struct fw_cdev_event_phy_packet without_tstamp; + } phy_packet; }; struct inbound_phy_packet_event { struct event event; - struct fw_cdev_event_phy_packet phy_packet; + union { + struct fw_cdev_event_phy_packet without_tstamp; + } phy_packet; }; #ifdef CONFIG_COMPAT @@ -1549,26 +1553,41 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, { struct outbound_phy_packet_event *e = container_of(packet, struct outbound_phy_packet_event, p); - struct client *e_client; + struct client *e_client = e->client; + u32 rcode; + struct fw_cdev_event_phy_packet *pp; switch (status) { - /* expected: */ - case ACK_COMPLETE: e->phy_packet.rcode = RCODE_COMPLETE; break; - /* should never happen with PHY packets: */ - case ACK_PENDING: e->phy_packet.rcode = RCODE_COMPLETE; break; + // expected: + case ACK_COMPLETE: + rcode = RCODE_COMPLETE; + break; + // should never happen with PHY packets: + case ACK_PENDING: + rcode = RCODE_COMPLETE; + break; case ACK_BUSY_X: case ACK_BUSY_A: - case ACK_BUSY_B: e->phy_packet.rcode = RCODE_BUSY; break; - case ACK_DATA_ERROR: e->phy_packet.rcode = RCODE_DATA_ERROR; break; - case ACK_TYPE_ERROR: e->phy_packet.rcode = RCODE_TYPE_ERROR; break; - /* stale generation; cancelled; on certain controllers: no ack */ - default: e->phy_packet.rcode = status; break; + case ACK_BUSY_B: + rcode = RCODE_BUSY; + break; + case ACK_DATA_ERROR: + rcode = RCODE_DATA_ERROR; + break; + case ACK_TYPE_ERROR: + rcode = RCODE_TYPE_ERROR; + break; + // stale generation; cancelled; on certain controllers: no ack + default: + rcode = status; + break; } - e->phy_packet.data[0] = packet->timestamp; - e_client = e->client; - queue_event(e->client, &e->event, &e->phy_packet, - sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); + pp = &e->phy_packet.without_tstamp; + pp->rcode = rcode; + pp->data[0] = packet->timestamp; + queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, NULL, 0); + client_put(e_client); } @@ -1577,6 +1596,7 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) struct fw_cdev_send_phy_packet *a = &arg->send_phy_packet; struct fw_card *card = client->device->card; struct outbound_phy_packet_event *e; + struct fw_cdev_event_phy_packet *pp; /* Access policy: Allow this ioctl only on local nodes' device files. */ if (!client->device->is_local) @@ -1595,10 +1615,12 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) e->p.header[2] = a->data[1]; e->p.header_length = 12; e->p.callback = outbound_phy_packet_callback; - e->phy_packet.closure = a->closure; - e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT; + + pp = &e->phy_packet.without_tstamp; + pp->closure = a->closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT; if (is_ping_packet(a->data)) - e->phy_packet.length = 4; + pp->length = 4; card->driver->send_request(card, &e->p); @@ -1633,18 +1655,20 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p) spin_lock_irqsave(&card->lock, flags); list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) { + struct fw_cdev_event_phy_packet *pp; + e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC); if (e == NULL) break; - e->phy_packet.closure = client->phy_receiver_closure; - e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; - e->phy_packet.rcode = RCODE_COMPLETE; - e->phy_packet.length = 8; - e->phy_packet.data[0] = p->header[1]; - e->phy_packet.data[1] = p->header[2]; - queue_event(client, &e->event, - &e->phy_packet, sizeof(e->phy_packet) + 8, NULL, 0); + pp = &e->phy_packet.without_tstamp; + pp->closure = client->phy_receiver_closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; + pp->rcode = RCODE_COMPLETE; + pp->length = 8; + pp->data[0] = p->header[1]; + pp->data[1] = p->header[2]; + queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); } spin_unlock_irqrestore(&card->lock, flags); -- cgit v1.2.3 From fe971f9163b67b5338dfe4a0e4ce1cfa1b6cd325 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 30 May 2023 08:12:40 +0900 Subject: firewire: cdev: implement new event relevant to phy packet with time stamp In 1394 OHCI, the OUTPUT_LAST descriptor of Asynchronous Transmit (AT) context has timeStamp field, in which 1394 OHCI controller record the isochronous cycle when the packet was sent for the request subaction. Additionally, the trailing quadlet of Asynchronous Receive (AR) context has timeStamp field as well in which 1394 OHCI controller record the isochronous cycle when the packet arrived. The time stamps are also available for the cases to send and receive phy packet. This commit implements new events with time stamp field for user space. Link: https://lore.kernel.org/r/20230529113406.986289-13-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-cdev.c | 90 +++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 22 deletions(-) (limited to 'drivers/firewire/core-cdev.c') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 2220de3c945e..6274b86eb943 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -206,6 +206,7 @@ struct outbound_phy_packet_event { struct fw_packet p; union { struct fw_cdev_event_phy_packet without_tstamp; + struct fw_cdev_event_phy_packet2 with_tstamp; } phy_packet; }; @@ -213,6 +214,7 @@ struct inbound_phy_packet_event { struct event event; union { struct fw_cdev_event_phy_packet without_tstamp; + struct fw_cdev_event_phy_packet2 with_tstamp; } phy_packet; }; @@ -1555,7 +1557,6 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, container_of(packet, struct outbound_phy_packet_event, p); struct client *e_client = e->client; u32 rcode; - struct fw_cdev_event_phy_packet *pp; switch (status) { // expected: @@ -1583,10 +1584,31 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, break; } - pp = &e->phy_packet.without_tstamp; - pp->rcode = rcode; - pp->data[0] = packet->timestamp; - queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, NULL, 0); + switch (e->phy_packet.without_tstamp.type) { + case FW_CDEV_EVENT_PHY_PACKET_SENT: + { + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; + + pp->rcode = rcode; + pp->data[0] = packet->timestamp; + queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, + NULL, 0); + break; + } + case FW_CDEV_EVENT_PHY_PACKET_SENT2: + { + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; + + pp->rcode = rcode; + pp->tstamp = packet->timestamp; + queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, + NULL, 0); + break; + } + default: + WARN_ON(1); + break; + } client_put(e_client); } @@ -1596,13 +1618,12 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) struct fw_cdev_send_phy_packet *a = &arg->send_phy_packet; struct fw_card *card = client->device->card; struct outbound_phy_packet_event *e; - struct fw_cdev_event_phy_packet *pp; /* Access policy: Allow this ioctl only on local nodes' device files. */ if (!client->device->is_local) return -ENOSYS; - e = kzalloc(sizeof(*e) + 4, GFP_KERNEL); + e = kzalloc(sizeof(*e) + sizeof(a->data), GFP_KERNEL); if (e == NULL) return -ENOMEM; @@ -1616,11 +1637,23 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) e->p.header_length = 12; e->p.callback = outbound_phy_packet_callback; - pp = &e->phy_packet.without_tstamp; - pp->closure = a->closure; - pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT; - if (is_ping_packet(a->data)) - pp->length = 4; + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; + + pp->closure = a->closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT; + if (is_ping_packet(a->data)) + pp->length = 4; + } else { + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; + + pp->closure = a->closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT2; + // Keep the data field so that application can match the response event to the + // request. + pp->length = sizeof(a->data); + memcpy(pp->data, a->data, sizeof(a->data)); + } card->driver->send_request(card, &e->p); @@ -1655,20 +1688,33 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p) spin_lock_irqsave(&card->lock, flags); list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) { - struct fw_cdev_event_phy_packet *pp; - e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC); if (e == NULL) break; - pp = &e->phy_packet.without_tstamp; - pp->closure = client->phy_receiver_closure; - pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; - pp->rcode = RCODE_COMPLETE; - pp->length = 8; - pp->data[0] = p->header[1]; - pp->data[1] = p->header[2]; - queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; + + pp->closure = client->phy_receiver_closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; + pp->rcode = RCODE_COMPLETE; + pp->length = 8; + pp->data[0] = p->header[1]; + pp->data[1] = p->header[2]; + queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); + } else { + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; + + pp = &e->phy_packet.with_tstamp; + pp->closure = client->phy_receiver_closure; + pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED2; + pp->rcode = RCODE_COMPLETE; + pp->length = 8; + pp->tstamp = p->timestamp; + pp->data[0] = p->header[1]; + pp->data[1] = p->header[2]; + queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); + } } spin_unlock_irqrestore(&card->lock, flags); -- cgit v1.2.3