diff options
Diffstat (limited to 'drivers/firewire/core-card.c')
| -rw-r--r-- | drivers/firewire/core-card.c | 24 | 
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 9dcb30466ec..371713ff026 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -231,7 +231,7 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)  static void fw_card_bm_work(struct work_struct *work)  {  	struct fw_card *card = container_of(work, struct fw_card, work.work); -	struct fw_device *root_device; +	struct fw_device *root_device, *irm_device;  	struct fw_node *root_node;  	unsigned long flags;  	int root_id, new_root_id, irm_id, local_id; @@ -239,6 +239,7 @@ static void fw_card_bm_work(struct work_struct *work)  	bool do_reset = false;  	bool root_device_is_running;  	bool root_device_is_cmc; +	bool irm_is_1394_1995_only;  	spin_lock_irqsave(&card->lock, flags); @@ -248,12 +249,18 @@ static void fw_card_bm_work(struct work_struct *work)  	}  	generation = card->generation; +  	root_node = card->root_node;  	fw_node_get(root_node);  	root_device = root_node->data;  	root_device_is_running = root_device &&  			atomic_read(&root_device->state) == FW_DEVICE_RUNNING;  	root_device_is_cmc = root_device && root_device->cmc; + +	irm_device = card->irm_node->data; +	irm_is_1394_1995_only = irm_device && irm_device->config_rom && +			(irm_device->config_rom[2] & 0x000000f0) == 0; +  	root_id  = root_node->node_id;  	irm_id   = card->irm_node->node_id;  	local_id = card->local_node->node_id; @@ -276,8 +283,15 @@ static void fw_card_bm_work(struct work_struct *work)  		if (!card->irm_node->link_on) {  			new_root_id = local_id; -			fw_notify("IRM has link off, making local node (%02x) root.\n", -				  new_root_id); +			fw_notify("%s, making local node (%02x) root.\n", +				  "IRM has link off", new_root_id); +			goto pick_me; +		} + +		if (irm_is_1394_1995_only) { +			new_root_id = local_id; +			fw_notify("%s, making local node (%02x) root.\n", +				  "IRM is not 1394a compliant", new_root_id);  			goto pick_me;  		} @@ -316,8 +330,8 @@ static void fw_card_bm_work(struct work_struct *work)  			 * root, and thus, IRM.  			 */  			new_root_id = local_id; -			fw_notify("BM lock failed, making local node (%02x) root.\n", -				  new_root_id); +			fw_notify("%s, making local node (%02x) root.\n", +				  "BM lock failed", new_root_id);  			goto pick_me;  		}  	} else if (card->bm_generation != generation) {  |