Commit fc383796 authored by Stefan Richter's avatar Stefan Richter

firewire: ohci: fix Agere FW643 and multiple cameras

An Agere FW643 OHCI 1.1 card works fine for video reception from one
camera but fails early if receiving from two cameras.  After a short
while, no IR IRQ events occur and the context control register does not
react anymore.  This happens regardless whether both IR DMA contexts are
dual-buffer or one is dual-buffer and the other packet-per-buffer.

This can be worked around by disabling dual buffer DMA mode entirely.
http://sourceforge.net/mailarchive/message.php?msg_name=4A7C0594.2020208%40gmail.com
(Reported by Samuel Audet.)

In another report (by Jonathan Cameron), an FW643 works OK with two
cameras in dual buffer mode.  Whether this is due to different chip
revisions or different usage patterns (different video formats) is not
yet clear.  However, as far as the current capabilities of
firewire-core's isochronous I/O interface are concerned, simply
switching off dual-buffer on non-working and working FW643s alike is not
a problem in practice.  We only need to revisit this issue if we are
going to enhance the interface, e.g. so that applications can explicitly
choose modes.
Reported-by: default avatarSamuel Audet <samuel.audet@gmail.com>
Reported-by: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 1821bc19
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev) ...@@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev)
#define ohci_pmac_off(dev) #define ohci_pmac_off(dev)
#endif /* CONFIG_PPC_PMAC */ #endif /* CONFIG_PPC_PMAC */
#define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
static int __devinit pci_probe(struct pci_dev *dev, static int __devinit pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
...@@ -2422,6 +2426,11 @@ static int __devinit pci_probe(struct pci_dev *dev, ...@@ -2422,6 +2426,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
/* dual-buffer mode is broken if more than one IR context is active */
if (dev->vendor == PCI_VENDOR_ID_AGERE &&
dev->device == PCI_DEVICE_ID_AGERE_FW643)
ohci->use_dualbuffer = false;
/* x86-32 currently doesn't use highmem for dma_alloc_coherent */ /* x86-32 currently doesn't use highmem for dma_alloc_coherent */
#if !defined(CONFIG_X86_32) #if !defined(CONFIG_X86_32)
/* dual-buffer mode is broken with descriptor addresses above 2G */ /* dual-buffer mode is broken with descriptor addresses above 2G */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment