summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorClemens Ladisch <cladisch@fastmail.net>2009-12-24 12:05:58 +0100
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-12-29 19:58:16 +0100
commitdb5d247ae811f49185a71e703b65acad845e4b18 (patch)
tree630586f3bdeea2df01c349d3cf27fb2e6317370c /drivers/media
parentLinux 2.6.33-rc2 (diff)
downloadlinux-db5d247ae811f49185a71e703b65acad845e4b18.tar.xz
linux-db5d247ae811f49185a71e703b65acad845e4b18.zip
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)
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c12
1 files changed, 2 insertions, 10 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
index fe44789ab037..6223bf01efe9 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -202,14 +202,8 @@ static void handle_fcp(struct fw_card *card, struct fw_request *request,
unsigned long flags;
int su;
- if ((tcode != TCODE_WRITE_QUADLET_REQUEST &&
- tcode != TCODE_WRITE_BLOCK_REQUEST) ||
- offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE ||
- length == 0 ||
- (((u8 *)payload)[0] & 0xf0) != 0) {
- fw_send_response(card, request, RCODE_TYPE_ERROR);
+ if (length < 2 || (((u8 *)payload)[0] & 0xf0) != 0)
return;
- }
su = ((u8 *)payload)[1] & 0x7;
@@ -230,10 +224,8 @@ static void handle_fcp(struct fw_card *card, struct fw_request *request,
}
spin_unlock_irqrestore(&node_list_lock, flags);
- if (fdtv) {
+ if (fdtv)
avc_recv(fdtv, payload, length);
- fw_send_response(card, request, RCODE_COMPLETE);
- }
}
static struct fw_address_handler fcp_handler = {