Skip to content

Commit e699600

Browse files
takaswietiwai
authored andcommitted
firewire: cdev: obsolete NULL check to detect IEC 61883-1 FCP region
In the character device, the listener to address space should distinguish whether the request is to IEC 61883-1 FCP region or not. The user space application needs to access to the object of request in enough later by read(2), while the core function releases the object of request in the FCP case after completing the callback to handler. The handler guarantees the access safe by some way. It's done by duplication of the object after NULL check to the request, since core function passes NULL in the FCP case. It's inconvenient since the object of request includes some helpful information. It's better to add another way to check whether the request is to FCP region or not. Conveniently the file of transaction layer includes local implementation for the purpose. This commit moves it to module local file and use it instead of the NULL check, then the result of check is stored to per-client data for the inbound transaction so that the result can be referred by later to release the data. Signed-off-by: Takashi Sakamoto <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 13a55d6 commit e699600

File tree

4 files changed

+25
-22
lines changed

4 files changed

+25
-22
lines changed

drivers/firewire/core-cdev.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct inbound_transaction_resource {
111111
struct client_resource resource;
112112
struct fw_card *card;
113113
struct fw_request *request;
114+
bool is_fcp;
114115
void *data;
115116
size_t length;
116117
};
@@ -643,18 +644,13 @@ static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
643644
client->device->max_speed);
644645
}
645646

646-
static inline bool is_fcp_request(struct fw_request *request)
647-
{
648-
return request == NULL;
649-
}
650-
651647
static void release_request(struct client *client,
652648
struct client_resource *resource)
653649
{
654650
struct inbound_transaction_resource *r = container_of(resource,
655651
struct inbound_transaction_resource, resource);
656652

657-
if (is_fcp_request(r->request))
653+
if (r->is_fcp)
658654
kfree(r->data);
659655
else
660656
fw_send_response(r->card, r->request, RCODE_CONFLICT_ERROR);
@@ -669,6 +665,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
669665
void *payload, size_t length, void *callback_data)
670666
{
671667
struct address_handler_resource *handler = callback_data;
668+
bool is_fcp = is_in_fcp_region(offset, length);
672669
struct inbound_transaction_resource *r;
673670
struct inbound_transaction_event *e;
674671
size_t event_size0;
@@ -685,10 +682,11 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
685682

686683
r->card = card;
687684
r->request = request;
685+
r->is_fcp = is_fcp;
688686
r->data = payload;
689687
r->length = length;
690688

691-
if (is_fcp_request(request)) {
689+
if (is_fcp) {
692690
/*
693691
* FIXME: Let core-transaction.c manage a
694692
* single reference-counted copy?
@@ -743,7 +741,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
743741
kfree(e);
744742
kfree(fcp_frame);
745743

746-
if (!is_fcp_request(request))
744+
if (!is_fcp)
747745
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
748746

749747
fw_card_put(card);
@@ -819,7 +817,7 @@ static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
819817

820818
r = container_of(resource, struct inbound_transaction_resource,
821819
resource);
822-
if (is_fcp_request(r->request)) {
820+
if (r->is_fcp) {
823821
kfree(r->data);
824822
goto out;
825823
}

drivers/firewire/core-transaction.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -535,12 +535,6 @@ const struct fw_address_region fw_unit_space_region =
535535
{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
536536
#endif /* 0 */
537537

538-
static bool is_in_fcp_region(u64 offset, size_t length)
539-
{
540-
return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
541-
offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
542-
}
543-
544538
/**
545539
* fw_core_add_address_handler() - register for incoming requests
546540
* @handler: callback
@@ -822,12 +816,18 @@ static struct fw_request *allocate_request(struct fw_card *card,
822816
return request;
823817
}
824818

819+
/**
820+
* fw_send_response: - send response packet for asynchronous transaction.
821+
* @card: interface to send the response at.
822+
* @request: firewire request data for the transaction.
823+
* @rcode: response code to send.
824+
*
825+
* Submit a response packet into the asynchronous response transmission queue. The @request
826+
* is going to be released when the transmission successfully finishes later.
827+
*/
825828
void fw_send_response(struct fw_card *card,
826829
struct fw_request *request, int rcode)
827830
{
828-
if (WARN_ONCE(!request, "invalid for FCP address handlers"))
829-
return;
830-
831831
/* unified transaction or broadcast transaction: don't respond */
832832
if (request->ack != ACK_PENDING ||
833833
HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
@@ -935,7 +935,7 @@ static void handle_fcp_region_request(struct fw_card *card,
935935
rcu_read_lock();
936936
list_for_each_entry_rcu(handler, &address_handler_list, link) {
937937
if (is_enclosing_handler(handler, offset, request->length))
938-
handler->address_callback(card, NULL, tcode,
938+
handler->address_callback(card, request, tcode,
939939
destination, source,
940940
p->generation, offset,
941941
request->data,

drivers/firewire/core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,10 @@ static inline bool is_ping_packet(u32 *data)
257257
return (data[0] & 0xc0ffffff) == 0 && ~data[0] == data[1];
258258
}
259259

260+
static inline bool is_in_fcp_region(u64 offset, size_t length)
261+
{
262+
return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
263+
offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
264+
}
265+
260266
#endif /* _FIREWIRE_CORE_H */

include/linux/firewire.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,8 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
278278
* Otherwise there is a danger of recursion of inbound and outbound
279279
* transactions from and to the local node.
280280
*
281-
* The callback is responsible that either fw_send_response() or kfree()
282-
* is called on the @request, except for FCP registers for which the core
283-
* takes care of that.
281+
* The callback is responsible that fw_send_response() is called on the @request, except for FCP
282+
* registers for which the core takes care of that.
284283
*/
285284
typedef void (*fw_address_callback_t)(struct fw_card *card,
286285
struct fw_request *request,

0 commit comments

Comments
 (0)