Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 180014
b: refs/heads/master
c: 281e203
h: refs/heads/master
v: v3
  • Loading branch information
Stefan Richter committed Jan 26, 2010
1 parent 318ee7d commit 400d1e6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d3faf6f431bafb25f4b9926c50a7e5c267738c6
refs/heads/master: 281e20323ab72180137824a298ee9e21e6f9acf6
50 changes: 36 additions & 14 deletions trunk/drivers/firewire/core-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/preempt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
Expand Down Expand Up @@ -595,13 +596,20 @@ static int ioctl_send_request(struct client *client, void *buffer)
client->device->max_speed);
}

static inline bool is_fcp_request(struct fw_request *request)
{
return request == NULL;
}

static void release_request(struct client *client,
struct client_resource *resource)
{
struct inbound_transaction_resource *r = container_of(resource,
struct inbound_transaction_resource, resource);

if (r->request)
if (is_fcp_request(r->request))
kfree(r->data);
else
fw_send_response(client->device->card, r->request,
RCODE_CONFLICT_ERROR);
kfree(r);
Expand All @@ -616,6 +624,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
struct address_handler_resource *handler = callback_data;
struct inbound_transaction_resource *r;
struct inbound_transaction_event *e;
void *fcp_frame = NULL;
int ret;

r = kmalloc(sizeof(*r), GFP_ATOMIC);
Expand All @@ -627,6 +636,18 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
r->data = payload;
r->length = length;

if (is_fcp_request(request)) {
/*
* 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)
Expand All @@ -640,13 +661,15 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
e->request.closure = handler->closure;

queue_event(handler->client, &e->event,
&e->request, sizeof(e->request), payload, length);
&e->request, sizeof(e->request), r->data, length);
return;

failed:
kfree(r);
kfree(e);
if (request)
kfree(fcp_frame);

if (!is_fcp_request(request))
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
}

Expand Down Expand Up @@ -717,18 +740,17 @@ static int ioctl_send_response(struct client *client, void *buffer)

r = container_of(resource, struct inbound_transaction_resource,
resource);
if (r->request) {
if (request->length < r->length)
r->length = request->length;
if (copy_from_user(r->data, u64_to_uptr(request->data),
r->length)) {
ret = -EFAULT;
kfree(r->request);
goto out;
}
fw_send_response(client->device->card, r->request,
request->rcode);
if (is_fcp_request(r->request))
goto out;

if (request->length < r->length)
r->length = request->length;
if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
ret = -EFAULT;
kfree(r->request);
goto out;
}
fw_send_response(client->device->card, r->request, request->rcode);
out:
kfree(r);

Expand Down

0 comments on commit 400d1e6

Please sign in to comment.