@@ -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
212213struct 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