Skip to content

Commit fe971f9

Browse files
committed
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 <o-takashi@sakamocchi.jp>
1 parent e27b393 commit fe971f9

1 file changed

Lines changed: 68 additions & 22 deletions

File tree

drivers/firewire/core-cdev.c

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,15 @@ struct outbound_phy_packet_event {
206206
struct fw_packet p;
207207
union {
208208
struct fw_cdev_event_phy_packet without_tstamp;
209+
struct fw_cdev_event_phy_packet2 with_tstamp;
209210
} phy_packet;
210211
};
211212

212213
struct inbound_phy_packet_event {
213214
struct event event;
214215
union {
215216
struct fw_cdev_event_phy_packet without_tstamp;
217+
struct fw_cdev_event_phy_packet2 with_tstamp;
216218
} phy_packet;
217219
};
218220

@@ -1555,7 +1557,6 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
15551557
container_of(packet, struct outbound_phy_packet_event, p);
15561558
struct client *e_client = e->client;
15571559
u32 rcode;
1558-
struct fw_cdev_event_phy_packet *pp;
15591560

15601561
switch (status) {
15611562
// expected:
@@ -1583,10 +1584,31 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
15831584
break;
15841585
}
15851586

1586-
pp = &e->phy_packet.without_tstamp;
1587-
pp->rcode = rcode;
1588-
pp->data[0] = packet->timestamp;
1589-
queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, NULL, 0);
1587+
switch (e->phy_packet.without_tstamp.type) {
1588+
case FW_CDEV_EVENT_PHY_PACKET_SENT:
1589+
{
1590+
struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp;
1591+
1592+
pp->rcode = rcode;
1593+
pp->data[0] = packet->timestamp;
1594+
queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length,
1595+
NULL, 0);
1596+
break;
1597+
}
1598+
case FW_CDEV_EVENT_PHY_PACKET_SENT2:
1599+
{
1600+
struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp;
1601+
1602+
pp->rcode = rcode;
1603+
pp->tstamp = packet->timestamp;
1604+
queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length,
1605+
NULL, 0);
1606+
break;
1607+
}
1608+
default:
1609+
WARN_ON(1);
1610+
break;
1611+
}
15901612

15911613
client_put(e_client);
15921614
}
@@ -1596,13 +1618,12 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
15961618
struct fw_cdev_send_phy_packet *a = &arg->send_phy_packet;
15971619
struct fw_card *card = client->device->card;
15981620
struct outbound_phy_packet_event *e;
1599-
struct fw_cdev_event_phy_packet *pp;
16001621

16011622
/* Access policy: Allow this ioctl only on local nodes' device files. */
16021623
if (!client->device->is_local)
16031624
return -ENOSYS;
16041625

1605-
e = kzalloc(sizeof(*e) + 4, GFP_KERNEL);
1626+
e = kzalloc(sizeof(*e) + sizeof(a->data), GFP_KERNEL);
16061627
if (e == NULL)
16071628
return -ENOMEM;
16081629

@@ -1616,11 +1637,23 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
16161637
e->p.header_length = 12;
16171638
e->p.callback = outbound_phy_packet_callback;
16181639

1619-
pp = &e->phy_packet.without_tstamp;
1620-
pp->closure = a->closure;
1621-
pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT;
1622-
if (is_ping_packet(a->data))
1623-
pp->length = 4;
1640+
if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) {
1641+
struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp;
1642+
1643+
pp->closure = a->closure;
1644+
pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT;
1645+
if (is_ping_packet(a->data))
1646+
pp->length = 4;
1647+
} else {
1648+
struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp;
1649+
1650+
pp->closure = a->closure;
1651+
pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT2;
1652+
// Keep the data field so that application can match the response event to the
1653+
// request.
1654+
pp->length = sizeof(a->data);
1655+
memcpy(pp->data, a->data, sizeof(a->data));
1656+
}
16241657

16251658
card->driver->send_request(card, &e->p);
16261659

@@ -1655,20 +1688,33 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p)
16551688
spin_lock_irqsave(&card->lock, flags);
16561689

16571690
list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) {
1658-
struct fw_cdev_event_phy_packet *pp;
1659-
16601691
e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
16611692
if (e == NULL)
16621693
break;
16631694

1664-
pp = &e->phy_packet.without_tstamp;
1665-
pp->closure = client->phy_receiver_closure;
1666-
pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED;
1667-
pp->rcode = RCODE_COMPLETE;
1668-
pp->length = 8;
1669-
pp->data[0] = p->header[1];
1670-
pp->data[1] = p->header[2];
1671-
queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0);
1695+
if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) {
1696+
struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp;
1697+
1698+
pp->closure = client->phy_receiver_closure;
1699+
pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED;
1700+
pp->rcode = RCODE_COMPLETE;
1701+
pp->length = 8;
1702+
pp->data[0] = p->header[1];
1703+
pp->data[1] = p->header[2];
1704+
queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0);
1705+
} else {
1706+
struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp;
1707+
1708+
pp = &e->phy_packet.with_tstamp;
1709+
pp->closure = client->phy_receiver_closure;
1710+
pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED2;
1711+
pp->rcode = RCODE_COMPLETE;
1712+
pp->length = 8;
1713+
pp->tstamp = p->timestamp;
1714+
pp->data[0] = p->header[1];
1715+
pp->data[1] = p->header[2];
1716+
queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0);
1717+
}
16721718
}
16731719

16741720
spin_unlock_irqrestore(&card->lock, flags);

0 commit comments

Comments
 (0)