firewire: cdev: use single object to dispatch event for request to IEC 61883-1 FCP region
The core function always passes the data of request to the callback of listener in any case. Additionally, the listener can maintain the lifetime of data by reference count. In character device, no need to duplicate the payload of request anymore to copy it to user space. This commit extends the lifetime of data to obsolete duplication of payload for request in character device. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20230120090344.296451-4-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
e699600232
commit
39859be853
|
@ -651,7 +651,7 @@ static void release_request(struct client *client,
|
|||
struct inbound_transaction_resource, resource);
|
||||
|
||||
if (r->is_fcp)
|
||||
kfree(r->data);
|
||||
fw_request_put(r->request);
|
||||
else
|
||||
fw_send_response(r->card, r->request, RCODE_CONFLICT_ERROR);
|
||||
|
||||
|
@ -669,12 +669,16 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
|
|||
struct inbound_transaction_resource *r;
|
||||
struct inbound_transaction_event *e;
|
||||
size_t event_size0;
|
||||
void *fcp_frame = NULL;
|
||||
int ret;
|
||||
|
||||
/* card may be different from handler->client->device->card */
|
||||
fw_card_get(card);
|
||||
|
||||
// Extend the lifetime of data for request so that its payload is safely accessible in
|
||||
// the process context for the client.
|
||||
if (is_fcp)
|
||||
fw_request_get(request);
|
||||
|
||||
r = kmalloc(sizeof(*r), GFP_ATOMIC);
|
||||
e = kmalloc(sizeof(*e), GFP_ATOMIC);
|
||||
if (r == NULL || e == NULL)
|
||||
|
@ -686,18 +690,6 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
|
|||
r->data = payload;
|
||||
r->length = length;
|
||||
|
||||
if (is_fcp) {
|
||||
/*
|
||||
* FIXME: Let core-transaction.c manage a
|
||||
* single reference-counted copy?
|
||||
*/
|
||||
fcp_frame = kmemdup(payload, length, GFP_ATOMIC);
|
||||
if (fcp_frame == NULL)
|
||||
goto failed;
|
||||
|
||||
r->data = fcp_frame;
|
||||
}
|
||||
|
||||
r->resource.release = release_request;
|
||||
ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
|
||||
if (ret < 0)
|
||||
|
@ -739,10 +731,11 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
|
|||
failed:
|
||||
kfree(r);
|
||||
kfree(e);
|
||||
kfree(fcp_frame);
|
||||
|
||||
if (!is_fcp)
|
||||
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
|
||||
else
|
||||
fw_request_put(request);
|
||||
|
||||
fw_card_put(card);
|
||||
}
|
||||
|
@ -818,7 +811,7 @@ static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
|
|||
r = container_of(resource, struct inbound_transaction_resource,
|
||||
resource);
|
||||
if (r->is_fcp) {
|
||||
kfree(r->data);
|
||||
fw_request_put(r->request);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue