Skip to content

Commit 39ce342

Browse files
committed
firewire: core: implement variations to send request and wait for response with time stamp
In the previous commit, the core function of Linux FireWire subsystem was changed for two cases to operate asynchronous transaction with or without time stamp. This commit changes kernel API for the two cases. Current kernel API, fw_send_request(), is changed to be static inline function to call __fw_send_request(), which receives two argument for union and flag of callback function. The new kernel API, fw_send_request_with_tstamp() is also added as static inline function, too. When calling, the two arguments are copied to internal structure, then used in softIRQ context. Link: https://lore.kernel.org/r/20230529113406.986289-7-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent dcadfd7 commit 39ce342

2 files changed

Lines changed: 92 additions & 18 deletions

File tree

drivers/firewire/core-transaction.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ static int allocate_tlabel(struct fw_card *card)
316316
}
317317

318318
/**
319-
* fw_send_request() - submit a request packet for transmission
319+
* __fw_send_request() - submit a request packet for transmission to generate callback for response
320+
* subaction with or without time stamp.
320321
* @card: interface to send the request at
321322
* @t: transaction instance to which the request belongs
322323
* @tcode: transaction code
@@ -326,7 +327,9 @@ static int allocate_tlabel(struct fw_card *card)
326327
* @offset: 48bit wide offset into destination's address space
327328
* @payload: data payload for the request subaction
328329
* @length: length of the payload, in bytes
329-
* @callback: function to be called when the transaction is completed
330+
* @callback: union of two functions whether to receive time stamp or not for response
331+
* subaction.
332+
* @with_tstamp: Whether to receive time stamp or not for response subaction.
330333
* @callback_data: data to be passed to the transaction completion callback
331334
*
332335
* Submit a request packet into the asynchronous request transmission queue.
@@ -363,10 +366,10 @@ static int allocate_tlabel(struct fw_card *card)
363366
* transaction completion and hence execution of @callback may happen even
364367
* before fw_send_request() returns.
365368
*/
366-
void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
367-
int destination_id, int generation, int speed,
368-
unsigned long long offset, void *payload, size_t length,
369-
fw_transaction_callback_t callback, void *callback_data)
369+
void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
370+
int destination_id, int generation, int speed, unsigned long long offset,
371+
void *payload, size_t length, union fw_transaction_callback callback,
372+
bool with_tstamp, void *callback_data)
370373
{
371374
unsigned long flags;
372375
int tlabel;
@@ -381,22 +384,32 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
381384
tlabel = allocate_tlabel(card);
382385
if (tlabel < 0) {
383386
spin_unlock_irqrestore(&card->lock, flags);
384-
callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
387+
if (!with_tstamp) {
388+
callback.without_tstamp(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
389+
} else {
390+
// Timestamping on behalf of hardware.
391+
u32 curr_cycle_time = 0;
392+
u32 tstamp;
393+
394+
(void)fw_card_read_cycle_time(card, &curr_cycle_time);
395+
tstamp = cycle_time_to_ohci_tstamp(curr_cycle_time);
396+
397+
callback.with_tstamp(card, RCODE_SEND_ERROR, tstamp, tstamp, NULL, 0,
398+
callback_data);
399+
}
385400
return;
386401
}
387402

388403
t->node_id = destination_id;
389404
t->tlabel = tlabel;
390405
t->card = card;
391406
t->is_split_transaction = false;
392-
timer_setup(&t->split_timeout_timer,
393-
split_transaction_timeout_callback, 0);
394-
t->callback.without_tstamp = callback;
395-
t->with_tstamp = false;
407+
timer_setup(&t->split_timeout_timer, split_transaction_timeout_callback, 0);
408+
t->callback = callback;
409+
t->with_tstamp = with_tstamp;
396410
t->callback_data = callback_data;
397411

398-
fw_fill_request(&t->packet, tcode, t->tlabel,
399-
destination_id, card->node_id, generation,
412+
fw_fill_request(&t->packet, tcode, t->tlabel, destination_id, card->node_id, generation,
400413
speed, offset, payload, length);
401414
t->packet.callback = transmit_complete_callback;
402415

@@ -406,7 +419,7 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
406419

407420
card->driver->send_request(card, &t->packet);
408421
}
409-
EXPORT_SYMBOL(fw_send_request);
422+
EXPORT_SYMBOL_GPL(__fw_send_request);
410423

411424
struct transaction_callback_data {
412425
struct completion done;

include/linux/firewire.h

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,71 @@ void fw_send_response(struct fw_card *card,
356356
struct fw_request *request, int rcode);
357357
int fw_get_request_speed(struct fw_request *request);
358358
u32 fw_request_get_timestamp(const struct fw_request *request);
359-
void fw_send_request(struct fw_card *card, struct fw_transaction *t,
360-
int tcode, int destination_id, int generation, int speed,
361-
unsigned long long offset, void *payload, size_t length,
362-
fw_transaction_callback_t callback, void *callback_data);
359+
360+
void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
361+
int destination_id, int generation, int speed, unsigned long long offset,
362+
void *payload, size_t length, union fw_transaction_callback callback,
363+
bool with_tstamp, void *callback_data);
364+
365+
/**
366+
* fw_send_request() - submit a request packet for transmission to generate callback for response
367+
* subaction without time stamp.
368+
* @card: interface to send the request at
369+
* @t: transaction instance to which the request belongs
370+
* @tcode: transaction code
371+
* @destination_id: destination node ID, consisting of bus_ID and phy_ID
372+
* @generation: bus generation in which request and response are valid
373+
* @speed: transmission speed
374+
* @offset: 48bit wide offset into destination's address space
375+
* @payload: data payload for the request subaction
376+
* @length: length of the payload, in bytes
377+
* @callback: function to be called when the transaction is completed
378+
* @callback_data: data to be passed to the transaction completion callback
379+
*
380+
* A variation of __fw_send_request() to generate callback for response subaction without time
381+
* stamp.
382+
*/
383+
static inline void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
384+
int destination_id, int generation, int speed,
385+
unsigned long long offset, void *payload, size_t length,
386+
fw_transaction_callback_t callback, void *callback_data)
387+
{
388+
union fw_transaction_callback cb = {
389+
.without_tstamp = callback,
390+
};
391+
__fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload,
392+
length, cb, false, callback_data);
393+
}
394+
395+
/**
396+
* fw_send_request_with_tstamp() - submit a request packet for transmission to generate callback for
397+
* response with time stamp.
398+
* @card: interface to send the request at
399+
* @t: transaction instance to which the request belongs
400+
* @tcode: transaction code
401+
* @destination_id: destination node ID, consisting of bus_ID and phy_ID
402+
* @generation: bus generation in which request and response are valid
403+
* @speed: transmission speed
404+
* @offset: 48bit wide offset into destination's address space
405+
* @payload: data payload for the request subaction
406+
* @length: length of the payload, in bytes
407+
* @callback: function to be called when the transaction is completed
408+
* @callback_data: data to be passed to the transaction completion callback
409+
*
410+
* A variation of __fw_send_request() to generate callback for response subaction with time stamp.
411+
*/
412+
static inline void fw_send_request_with_tstamp(struct fw_card *card, struct fw_transaction *t,
413+
int tcode, int destination_id, int generation, int speed, unsigned long long offset,
414+
void *payload, size_t length, fw_transaction_callback_with_tstamp_t callback,
415+
void *callback_data)
416+
{
417+
union fw_transaction_callback cb = {
418+
.with_tstamp = callback,
419+
};
420+
__fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload,
421+
length, cb, true, callback_data);
422+
}
423+
363424
int fw_cancel_transaction(struct fw_card *card,
364425
struct fw_transaction *transaction);
365426
int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,

0 commit comments

Comments
 (0)