if (a->length != fw_get_response_length(r->request)) {
                ret = -EINVAL;
-               kfree(r->request);
+               fw_request_put(r->request);
                goto out;
        }
        if (copy_from_user(r->data, u64_to_uptr(a->data), a->length)) {
                ret = -EFAULT;
-               kfree(r->request);
+               fw_request_put(r->request);
                goto out;
        }
        fw_send_response(r->card, r->request, a->rcode);
 
 EXPORT_SYMBOL(fw_core_remove_address_handler);
 
 struct fw_request {
+       struct kref kref;
        struct fw_packet response;
        u32 request_header[4];
        int ack;
        u32 data[];
 };
 
+void fw_request_get(struct fw_request *request)
+{
+       kref_get(&request->kref);
+}
+
+static void release_request(struct kref *kref)
+{
+       struct fw_request *request = container_of(kref, struct fw_request, kref);
+
+       kfree(request);
+}
+
+void fw_request_put(struct fw_request *request)
+{
+       kref_put(&request->kref, release_request);
+}
+
 static void free_response_callback(struct fw_packet *packet,
                                   struct fw_card *card, int status)
 {
-       struct fw_request *request;
+       struct fw_request *request = container_of(packet, struct fw_request, response);
 
-       request = container_of(packet, struct fw_request, response);
-       kfree(request);
+       // Decrease the reference count since not at in-flight.
+       fw_request_put(request);
+
+       // Decrease the reference count to release the object.
+       fw_request_put(request);
 }
 
 int fw_get_response_length(struct fw_request *r)
        request = kmalloc(sizeof(*request) + length, GFP_ATOMIC);
        if (request == NULL)
                return NULL;
+       kref_init(&request->kref);
 
        request->response.speed = p->speed;
        request->response.timestamp =
        /* unified transaction or broadcast transaction: don't respond */
        if (request->ack != ACK_PENDING ||
            HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
-               kfree(request);
+               fw_request_put(request);
                return;
        }
 
                fw_fill_response(&request->response, request->request_header,
                                 rcode, NULL, 0);
 
+       // Increase the reference count so that the object is kept during in-flight.
+       fw_request_get(request);
+
        card->driver->send_response(card, &request->response);
 }
 EXPORT_SYMBOL(fw_send_response);
 
 void fw_fill_response(struct fw_packet *response, u32 *request_header,
                      int rcode, void *payload, size_t length);
 
+void fw_request_get(struct fw_request *request);
+void fw_request_put(struct fw_request *request);
+
 #define FW_PHY_CONFIG_NO_NODE_ID       -1
 #define FW_PHY_CONFIG_CURRENT_GAP_COUNT        -1
 void fw_send_phy_config(struct fw_card *card,