FireWire fixes
Linus, please pull from the fixes branch at
git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git fixes
to receive a small update of the IEEE 1394 (FireWire) subsystem. This addresses old but only recently reported bugs. Thanks.
Stefan Richter (2):
firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases
firewire: ohci: fix DMA unmapping in an error path
drivers/firewire/core-cdev.c | 24 +++++++++++++++++++++--- drivers/firewire/ohci.c | 9 +++++++-- 2 files changed, 28 insertions(+), 5 deletions(-)
Full log and diff:
commit a01e836087881dd9d824417190994c9b2b0f1dbb
Author: Stefan Richter <[email protected]> Date: Thu Aug 11 20:40:42 2011 +0200
firewire: ohci: fix DMA unmapping in an error path
If request_irq failed, we would pass wrong arguments to dma_free_coherent. https://bugzilla.redhat.com/show_bug.cgi?id=728185
drivers/firewire/ohci.c +7 -2
@@ -2178,8 +2178,13 @@ static int ohci_enable(struct fw_card *card, ohci_driver_name, ohci)) {fw_error ("Failed to allocate interrupt %d.\n" , dev->irq);pci_disable_msi (dev); -dma_free_coherent (ohci->card.device,CONFIG_ROM_SIZE , - ohci->config_rom, ohci->config_rom_bus); + +if (config_rom) { +dma_free_coherent (ohci->card.device,CONFIG_ROM_SIZE , + ohci->next_config_rom, + ohci->next_config_rom_bus); + ohci->next_config_rom =NULL ; + }return -EIO ; }
commit 9c1176b6a28850703ea6e3a0f0c703f6d6c61cd3
Author: Stefan Richter <[email protected]> Date: Thu Aug 11 00:06:04 2011 +0200
firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases
Clemens points out that we need to use compat_ptr() in order to safely cast from u64 to addresses of a 32-bit usermode client.
Before, our conversion went wrong
- in practice if the client cast from pointer to integer such that sign-extension happened, (libraw1394 and libdc1394 at least were not doing that, IOW were not affected)
or
- in theory on s390 (which doesn't have FireWire though) and on the tile architecture, regardless of what the client does.
The bug would usually be observed as the initial get_info ioctl failing with "Bad address" (EFAULT).
drivers/firewire/core-cdev.c +21 -3
@@ -216,15 +216,33 @@ struct inbound_phy_packet_event {struct fw_cdev_event_phy_packet phy_packet; }; -static inline void __user *u64_to_uptr (__u64 value) +#ifdef CONFIG_COMPAT +static void __user *u64_to_uptr (u64 value) +{ +if (is_compat_task ()) +return compat_ptr (value); +else +return (void __user *)(unsigned long )value; +} + +static u64 uptr_to_u64 (void __user *ptr) +{ +if (is_compat_task ()) +return ptr_to_compat (ptr); +else +return (u64 )(unsigned long )ptr; +} +#else +static inline void __user *u64_to_uptr (u64 value) {return (void __user *)(unsigned long )value; } -static inline __u64 uptr_to_u64 (void __user *ptr) +static inline u64 uptr_to_u64 (void __user *ptr) { -return (__u64 )(unsigned long )ptr; +return (u64 )(unsigned long )ptr; } +#endif /* CONFIG_COMPAT */ static int fw_device_op_open (struct inode *inode,struct file *file) {
Signature · 3 lines
Stefan Richter -=====-==-== =--- -==== http://arcgraph.de/sr/
[git pull] FireWire fix
Linus, please pull from the fixes branch at
git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git fixes
to receive a quirk handling update to the IEEE 1394 (FireWire) subsystem for some old first-generation i.LINK enabled camcorders.
This is not a complete solution yet, but a valid improvement on its own and suitable to be merged this late in the -rc phase. It is undecided yet whether the rest of the solution is going to be a more intrusive but general change to firewire-core transaction layer or a small but less general adjustment in userspace (libavc1394 and libiec61883).
Stefan Richter (1):
firewire: core: handle ack_busy when fetching the Config ROM
drivers/firewire/core-device.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-)
commit aaff12039ffd812d0c8bbff50b87b6f1f09bec3e
Author: Stefan Richter <[email protected]> Date: Sun Aug 7 15:20:18 2011 +0200
firewire: core: handle ack_busy when fetching the Config ROM
Some older Panasonic made camcorders (Panasonic AG-EZ30 and NV-DX110, Grundig Scenos DLC 2000) reject requests with ack_busy_X if a request is sent immediately after they sent a response to a prior transaction. This causes firewire-core to fail probing of the camcorder with "giving up on config rom for node id ...". Consequently, programs like kino or dvgrab are unaware of the presence of a camcorder.
Such transaction failures happen also with the ieee1394 driver stack (of the 2.4...2.6 kernel series until 2.6.36 inclusive) but with a lower likelihood, such that kino or dvgrab are generally able to use these camcorders via the older driver stack. The cause for firewire-ohci's or firewire-core's worse behavior is not yet known. Gap count optimization in firewire-core is not the cause. Perhaps the slightly higher latency of transaction completion in the older stack plays a role. (ieee1394:
AR-resp DMA context tasklet -> packet completion ktread -> user process;
firewire-core: tasklet -> user process.)
This change introduces retries and delays after ack_busy_X into firewire-core's Config ROM reader, such that at least firewire-core's probing and /dev/fw* creation are successful. This still leaves the problem that userland processes are facing transaction failures. gscanbus's built-in retry routines deal with them successfully, but neither kino's nor dvgrab's do ever succeed.
But at least DV capture with "dvgrab -noavc -card 0" works now. Live video preview in kino works too, but not actual capture.
One way to prevent Configuration ROM reading failures in application programs is to modify libraw1394 to synthesize read responses by means of firewire-core's Configuration ROM cache. This would only leave CMP and FCP transaction failures as a potential problem source for applications.
drivers/firewire/core-device.c +10 -5
@@ -455,15 +455,20 @@ static struct device_attribute fw_device_attributes[] = {static int read_rom (struct fw_device *device,int generation,int index,u32 *data) { -int rcode; +u64 offset = (CSR_REGISTER_BASE |CSR_CONFIG_ROM ) + index *4 ; +int i, rcode;/* device->node_id, accessed below, must not be older than generation */ smp_rmb (); - rcode =fw_run_transaction (device->card,TCODE_READ_QUADLET_REQUEST , - device->node_id, generation, device->max_speed, - (CSR_REGISTER_BASE |CSR_CONFIG_ROM ) + index *4 , - data,4 ); +for (i =10 ; i <100 ; i +=10 ) { + rcode =fw_run_transaction (device->card, +TCODE_READ_QUADLET_REQUEST , device->node_id, + generation, device->max_speed, offset, data,4 ); +if (rcode !=RCODE_BUSY ) +break ; +msleep (i); + }be32_to_cpus (data);return rcode;
Signature · 3 lines
Stefan Richter -=====-==-== =--- =-=-= http://arcgraph.de/sr/