mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
firewire: fix use of multiple AV/C devices, allow multiple FCP listeners
Control of more than one AV/C device at once --- e.g. camcorders, tape decks, audio devices, TV tuners --- failed or worked only unreliably, depending on driver implementation. This affected kernelspace and userspace drivers alike and was caused by firewire-core's inability to accept multiple registrations of FCP listeners. The fix allows multiple address handlers to be registered for the FCP command and response registers. When a request for these registers is received, all handlers are invoked, and the Firewire response is generated by the core and not by any handler. The cdev API does not change, i.e., userspace is still expected to send a response for FCP requests; this response is silently ignored. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (changelog, rebased, whitespace)
This commit is contained in:
parent
6b7b284958
commit
db5d247ae8
5 changed files with 119 additions and 44 deletions
|
@ -601,8 +601,9 @@ static void release_request(struct client *client,
|
|||
struct inbound_transaction_resource *r = container_of(resource,
|
||||
struct inbound_transaction_resource, resource);
|
||||
|
||||
fw_send_response(client->device->card, r->request,
|
||||
RCODE_CONFLICT_ERROR);
|
||||
if (r->request)
|
||||
fw_send_response(client->device->card, r->request,
|
||||
RCODE_CONFLICT_ERROR);
|
||||
kfree(r);
|
||||
}
|
||||
|
||||
|
@ -645,7 +646,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
|
|||
failed:
|
||||
kfree(r);
|
||||
kfree(e);
|
||||
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
|
||||
if (request)
|
||||
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
|
||||
}
|
||||
|
||||
static void release_address_handler(struct client *client,
|
||||
|
@ -715,15 +717,17 @@ static int ioctl_send_response(struct client *client, void *buffer)
|
|||
|
||||
r = container_of(resource, struct inbound_transaction_resource,
|
||||
resource);
|
||||
if (request->length < r->length)
|
||||
r->length = request->length;
|
||||
|
||||
if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
fw_send_response(client->device->card, r->request,
|
||||
request->rcode);
|
||||
}
|
||||
|
||||
fw_send_response(client->device->card, r->request, request->rcode);
|
||||
out:
|
||||
kfree(r);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue