]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/firewire/core-card.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / firewire / core-card.c
index be0492398ef9573be4eb752b78e485e5b22d0e71..24ff35511e2b1b6a890e7fc9f9499e75c74459d1 100644 (file)
@@ -75,6 +75,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1;
 #define BIB_IRMC               ((1) << 31)
 #define NODE_CAPABILITIES      0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */
 
+#define CANON_OUI              0x000085
+
 static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
 {
        struct fw_descriptor *desc;
@@ -284,6 +286,7 @@ static void bm_work(struct work_struct *work)
        bool root_device_is_running;
        bool root_device_is_cmc;
        bool irm_is_1394_1995_only;
+       bool keep_this_irm;
 
        spin_lock_irq(&card->lock);
 
@@ -305,6 +308,10 @@ static void bm_work(struct work_struct *work)
        irm_is_1394_1995_only = irm_device && irm_device->config_rom &&
                        (irm_device->config_rom[2] & 0x000000f0) == 0;
 
+       /* Canon MV5i works unreliably if it is not root node. */
+       keep_this_irm = irm_device && irm_device->config_rom &&
+                       irm_device->config_rom[3] >> 8 == CANON_OUI;
+
        root_id  = root_node->node_id;
        irm_id   = card->irm_node->node_id;
        local_id = card->local_node->node_id;
@@ -333,7 +340,7 @@ static void bm_work(struct work_struct *work)
                        goto pick_me;
                }
 
-               if (irm_is_1394_1995_only) {
+               if (irm_is_1394_1995_only && !keep_this_irm) {
                        new_root_id = local_id;
                        fw_notify("%s, making local node (%02x) root.\n",
                                  "IRM is not 1394a compliant", new_root_id);
@@ -382,7 +389,7 @@ static void bm_work(struct work_struct *work)
 
                spin_lock_irq(&card->lock);
 
-               if (rcode != RCODE_COMPLETE) {
+               if (rcode != RCODE_COMPLETE && !keep_this_irm) {
                        /*
                         * The lock request failed, maybe the IRM
                         * isn't really IRM capable after all. Let's