@@ -172,6 +172,7 @@ struct outbound_transaction_event {
172172 struct outbound_transaction_resource r ;
173173 union {
174174 struct fw_cdev_event_response without_tstamp ;
175+ struct fw_cdev_event_response2 with_tstamp ;
175176 } rsp ;
176177};
177178
@@ -538,41 +539,64 @@ static void release_transaction(struct client *client,
538539{
539540}
540541
541- static void complete_transaction (struct fw_card * card , int rcode ,
542- void * payload , size_t length , void * data )
542+ static void complete_transaction (struct fw_card * card , int rcode , u32 request_tstamp ,
543+ u32 response_tstamp , void * payload , size_t length , void * data )
543544{
544545 struct outbound_transaction_event * e = data ;
545- struct fw_cdev_event_response * rsp = & e -> rsp .without_tstamp ;
546546 struct client * client = e -> client ;
547547 unsigned long flags ;
548548
549- if (length < rsp -> length )
550- rsp -> length = length ;
551- if (rcode == RCODE_COMPLETE )
552- memcpy (rsp -> data , payload , rsp -> length );
553-
554549 spin_lock_irqsave (& client -> lock , flags );
555550 idr_remove (& client -> resource_idr , e -> r .resource .handle );
556551 if (client -> in_shutdown )
557552 wake_up (& client -> tx_flush_wait );
558553 spin_unlock_irqrestore (& client -> lock , flags );
559554
560- rsp -> type = FW_CDEV_EVENT_RESPONSE ;
561- rsp -> rcode = rcode ;
555+ switch (e -> rsp .without_tstamp .type ) {
556+ case FW_CDEV_EVENT_RESPONSE :
557+ {
558+ struct fw_cdev_event_response * rsp = & e -> rsp .without_tstamp ;
559+
560+ if (length < rsp -> length )
561+ rsp -> length = length ;
562+ if (rcode == RCODE_COMPLETE )
563+ memcpy (rsp -> data , payload , rsp -> length );
564+
565+ rsp -> rcode = rcode ;
566+
567+ // In the case that sizeof(*rsp) doesn't align with the position of the
568+ // data, and the read is short, preserve an extra copy of the data
569+ // to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
570+ // for short reads and some apps depended on it, this is both safe
571+ // and prudent for compatibility.
572+ if (rsp -> length <= sizeof (* rsp ) - offsetof(typeof (* rsp ), data ))
573+ queue_event (client , & e -> event , rsp , sizeof (* rsp ), rsp -> data , rsp -> length );
574+ else
575+ queue_event (client , & e -> event , rsp , sizeof (* rsp ) + rsp -> length , NULL , 0 );
562576
563- /*
564- * In the case that sizeof(*rsp) doesn't align with the position of the
565- * data, and the read is short, preserve an extra copy of the data
566- * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
567- * for short reads and some apps depended on it, this is both safe
568- * and prudent for compatibility.
569- */
570- if (rsp -> length <= sizeof (* rsp ) - offsetof(typeof (* rsp ), data ))
571- queue_event (client , & e -> event , rsp , sizeof (* rsp ),
572- rsp -> data , rsp -> length );
573- else
574- queue_event (client , & e -> event , rsp , sizeof (* rsp ) + rsp -> length ,
575- NULL , 0 );
577+ break ;
578+ }
579+ case FW_CDEV_EVENT_RESPONSE2 :
580+ {
581+ struct fw_cdev_event_response2 * rsp = & e -> rsp .with_tstamp ;
582+
583+ if (length < rsp -> length )
584+ rsp -> length = length ;
585+ if (rcode == RCODE_COMPLETE )
586+ memcpy (rsp -> data , payload , rsp -> length );
587+
588+ rsp -> rcode = rcode ;
589+ rsp -> request_tstamp = request_tstamp ;
590+ rsp -> response_tstamp = response_tstamp ;
591+
592+ queue_event (client , & e -> event , rsp , sizeof (* rsp ) + rsp -> length , NULL , 0 );
593+
594+ break ;
595+ default :
596+ WARN_ON (1 );
597+ break ;
598+ }
599+ }
576600
577601 /* Drop the idr's reference */
578602 client_put (client );
@@ -583,7 +607,6 @@ static int init_request(struct client *client,
583607 int destination_id , int speed )
584608{
585609 struct outbound_transaction_event * e ;
586- struct fw_cdev_event_response * rsp ;
587610 void * payload ;
588611 int ret ;
589612
@@ -600,10 +623,21 @@ static int init_request(struct client *client,
600623 return - ENOMEM ;
601624 e -> client = client ;
602625
603- rsp = & e -> rsp .without_tstamp ;
604- rsp -> length = request -> length ;
605- rsp -> closure = request -> closure ;
606- payload = rsp -> data ;
626+ if (client -> version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP ) {
627+ struct fw_cdev_event_response * rsp = & e -> rsp .without_tstamp ;
628+
629+ rsp -> type = FW_CDEV_EVENT_RESPONSE ;
630+ rsp -> length = request -> length ;
631+ rsp -> closure = request -> closure ;
632+ payload = rsp -> data ;
633+ } else {
634+ struct fw_cdev_event_response2 * rsp = & e -> rsp .with_tstamp ;
635+
636+ rsp -> type = FW_CDEV_EVENT_RESPONSE2 ;
637+ rsp -> length = request -> length ;
638+ rsp -> closure = request -> closure ;
639+ payload = rsp -> data ;
640+ }
607641
608642 if (request -> data && copy_from_user (payload , u64_to_uptr (request -> data ), request -> length )) {
609643 ret = - EFAULT ;
@@ -615,9 +649,9 @@ static int init_request(struct client *client,
615649 if (ret < 0 )
616650 goto failed ;
617651
618- fw_send_request (client -> device -> card , & e -> r .transaction , request -> tcode , destination_id ,
619- request -> generation , speed , request -> offset , payload , request -> length ,
620- complete_transaction , e );
652+ fw_send_request_with_tstamp (client -> device -> card , & e -> r .transaction , request -> tcode ,
653+ destination_id , request -> generation , speed , request -> offset ,
654+ payload , request -> length , complete_transaction , e );
621655 return 0 ;
622656
623657 failed :
0 commit comments