in core-cdev.c [576:621]
static int init_request(struct client *client,
struct fw_cdev_send_request *request,
int destination_id, int speed)
{
struct outbound_transaction_event *e;
int ret;
if (request->tcode != TCODE_STREAM_DATA &&
(request->length > 4096 || request->length > 512 << speed))
return -EIO;
if (request->tcode == TCODE_WRITE_QUADLET_REQUEST &&
request->length < 4)
return -EINVAL;
e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
if (e == NULL)
return -ENOMEM;
e->client = client;
e->response.length = request->length;
e->response.closure = request->closure;
if (request->data &&
copy_from_user(e->response.data,
u64_to_uptr(request->data), request->length)) {
ret = -EFAULT;
goto failed;
}
e->r.resource.release = release_transaction;
ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
if (ret < 0)
goto failed;
fw_send_request(client->device->card, &e->r.transaction,
request->tcode, destination_id, request->generation,
speed, request->offset, e->response.data,
request->length, complete_transaction, e);
return 0;
failed:
kfree(e);
return ret;
}