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);
 
        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)
        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)
  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);
 }
        r = container_of(resource, struct inbound_transaction_resource,
                         resource);
        if (r->is_fcp) {
-               kfree(r->data);
+               fw_request_put(r->request);
                goto out;
        }