From: Jody McIntyre <linux1394@modernduck.com>

Adds a disable_irm option to ieee1394.ko which disables all Isochronous
Resource Manager functionality, useful to work around bugs in our IRM
implementation.

Signed-off-by: Jody McIntyre <linux1394@modernduck.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/ieee1394/ieee1394.h      |   24 +++++++++++++++++++
 25-akpm/drivers/ieee1394/ieee1394_core.c |   16 ++++++++++++-
 25-akpm/drivers/ieee1394/ieee1394_core.h |    1 
 25-akpm/drivers/ieee1394/nodemgr.c       |    8 ++++++
 25-akpm/drivers/ieee1394/ohci1394.c      |    8 ++++--
 25-akpm/drivers/ieee1394/pcilynx.c       |   38 +++++++++++++++++--------------
 6 files changed, 75 insertions(+), 20 deletions(-)

diff -puN drivers/ieee1394/ieee1394_core.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/ieee1394_core.c
--- 25/drivers/ieee1394/ieee1394_core.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/ieee1394_core.c	Wed Jan 12 14:52:05 2005
@@ -56,6 +56,12 @@ static int disable_nodemgr = 0;
 module_param(disable_nodemgr, int, 0444);
 MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
 
+/* Disable Isochronous Resource Manager functionality */
+int hpsb_disable_irm = 0;
+module_param_named(disable_irm, hpsb_disable_irm, bool, 0);
+MODULE_PARM_DESC(disable_irm,
+		 "Disable Isochronous Resource Manager functionality.");
+
 /* We are GPL, so treat us special */
 MODULE_LICENSE("GPL");
 
@@ -81,7 +87,6 @@ static void dump_packet(const char *text
 
 static void queue_packet_complete(struct hpsb_packet *packet);
 
-
 /**
  * hpsb_set_packet_complete_task - set the task that runs when a packet
  * completes. You cannot call this more than once on a single packet
@@ -609,11 +614,14 @@ static void handle_packet_response(struc
         unsigned long flags;
 
         tlabel = (data[0] >> 10) & 0x3f;
+	printk("tlabel: %d, (data[1] >> 16): %04x\n", tlabel, (data[1] >> 16));
 
 	spin_lock_irqsave(&host->pending_packet_queue.lock, flags);
 
 	skb_queue_walk(&host->pending_packet_queue, skb) {
 		packet = (struct hpsb_packet *)skb->data;
+		printk("packet->tlabel: %d, packet->node_id: %04x\n",
+		       packet->tlabel, packet->node_id);
                 if ((packet->tlabel == tlabel)
                     && (packet->node_id == (data[1] >> 16))){
                         break;
@@ -1118,9 +1126,14 @@ static int __init ieee1394_init(void)
 
 	if (disable_nodemgr) {
 		HPSB_INFO("nodemgr functionality disabled");
+		hpsb_disable_irm = 1; /* to be safe */
 		return 0;
 	}
 
+	if (hpsb_disable_irm) {
+		HPSB_INFO("IRM functionality disabled");
+	}
+
 	ret = init_ieee1394_nodemgr();
 	if (ret < 0) {
 		HPSB_INFO("init nodemgr failed");
@@ -1203,6 +1216,7 @@ EXPORT_SYMBOL(hpsb_selfid_received);
 EXPORT_SYMBOL(hpsb_selfid_complete);
 EXPORT_SYMBOL(hpsb_packet_sent);
 EXPORT_SYMBOL(hpsb_packet_received);
+EXPORT_SYMBOL_GPL(hpsb_disable_irm);
 
 /** ieee1394_transactions.c **/
 EXPORT_SYMBOL(hpsb_get_tlabel);
diff -puN drivers/ieee1394/ieee1394_core.h~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/ieee1394_core.h
--- 25/drivers/ieee1394/ieee1394_core.h~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/ieee1394_core.h	Wed Jan 12 14:52:05 2005
@@ -219,6 +219,7 @@ static inline unsigned char ieee1394_fil
 	return file->f_dentry->d_inode->i_cindex;
 }
 
+extern int hpsb_disable_irm;
 
 /* Our sysfs bus entry */
 extern struct bus_type ieee1394_bus_type;
diff -puN drivers/ieee1394/ieee1394.h~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/ieee1394.h
--- 25/drivers/ieee1394/ieee1394.h~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/ieee1394.h	Wed Jan 12 14:52:05 2005
@@ -77,6 +77,30 @@ extern const char *hpsb_speedto_str[];
 #define SELFID_PORT_NONE         0x0
 
 
+/* 1394a PHY bitmasks */
+#define PHY_00_PHYSICAL_ID       0xFC
+#define PHY_00_R                 0x02 /* Root */
+#define PHY_00_PS                0x01 /* Power Status*/
+#define PHY_01_RHB               0x80 /* Root Hold-Off */
+#define PHY_01_IBR               0x80 /* Initiate Bus Reset */
+#define PHY_01_GAP_COUNT         0x3F
+#define PHY_02_EXTENDED          0xE0 /* 0x7 for 1394a-compliant PHY */
+#define PHY_02_TOTAL_PORTS       0x1F
+#define PHY_03_MAX_SPEED         0xE0
+#define PHY_03_DELAY             0x0F
+#define PHY_04_LCTRL             0x80 /* Link Active Report Control */
+#define PHY_04_CONTENDER         0x40
+#define PHY_04_JITTER            0x38
+#define PHY_04_PWR_CLASS         0x07 /* Power Class */
+#define PHY_05_WATCHDOG          0x80
+#define PHY_05_ISBR              0x40 /* Initiate Short Bus Reset */
+#define PHY_05_LOOP              0x20 /* Loop Detect */
+#define PHY_05_PWR_FAIL          0x10 /* Cable Power Failure Detect */
+#define PHY_05_TIMEOUT           0x08 /* Arbitration State Machine Timeout */
+#define PHY_05_PORT_EVENT        0x04 /* Port Event Detect */
+#define PHY_05_ENAB_ACCEL        0x02 /* Enable Arbitration Acceleration */
+#define PHY_05_ENAB_MULTI        0x01 /* Ena. Multispeed Packet Concatenation */
+
 #include <asm/byteorder.h>
 
 #ifdef __BIG_ENDIAN_BITFIELD
diff -puN drivers/ieee1394/nodemgr.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/nodemgr.c
--- 25/drivers/ieee1394/nodemgr.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/nodemgr.c	Wed Jan 12 14:52:05 2005
@@ -24,6 +24,7 @@
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
+#include "ieee1394_core.h"
 #include "hosts.h"
 #include "ieee1394_transactions.h"
 #include "highlevel.h"
@@ -1382,6 +1383,10 @@ static int nodemgr_do_irm_duties(struct 
 {
 	quadlet_t bc;
 
+
+	if (hpsb_disable_irm)
+		return 1;
+
 	/* if irm_id == -1 then there is no IRM on this bus */
 	if (!host->is_irm || host->irm_id == (nodeid_t)-1)
 		return 1;
@@ -1432,6 +1437,9 @@ static int nodemgr_check_irm_capability(
 	quadlet_t bc;
 	int status;
 
+	if (hpsb_disable_irm)
+		return 0;
+
 	if (host->is_irm)
 		return 1;
 
diff -puN drivers/ieee1394/ohci1394.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/ohci1394.c
--- 25/drivers/ieee1394/ohci1394.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/ohci1394.c	Wed Jan 12 14:52:05 2005
@@ -497,10 +497,12 @@ static void ohci_initialize(struct ti_oh
 	reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
 
 	/* Enable cycle timer and cycle master and set the IRM
-	 * contender bit in our self ID packets. */
-	reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_CycleTimerEnable |
+	 * contender bit in our self ID packets if appropriate. */
+	reg_write(ohci, OHCI1394_LinkControlSet,
+		  OHCI1394_LinkControl_CycleTimerEnable |
 		  OHCI1394_LinkControl_CycleMaster);
-	set_phy_reg_mask(ohci, 4, 0xc0);
+	set_phy_reg_mask(ohci, 4, PHY_04_LCTRL &
+			 (hpsb_disable_irm ? 0 : PHY_04_CONTENDER));
 
 	/* Set up self-id dma buffer */
 	reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
diff -puN drivers/ieee1394/pcilynx.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko drivers/ieee1394/pcilynx.c
--- 25/drivers/ieee1394/pcilynx.c~ieee1394-adds-a-disable_irm-option-to-ieee1394ko	Wed Jan 12 14:52:05 2005
+++ 25-akpm/drivers/ieee1394/pcilynx.c	Wed Jan 12 14:52:05 2005
@@ -79,7 +79,6 @@ static int skip_eeprom = 0;
 module_param(skip_eeprom, int, 0444);
 MODULE_PARM_DESC(skip_eeprom, "Use generic bus info block instead of serial eeprom (default = 0).");
 
-
 static struct hpsb_host_driver lynx_driver;
 static unsigned int card_id;
 
@@ -384,7 +383,8 @@ static quadlet_t generate_own_selfid(str
         lsid = 0x80400000 | ((phyreg[0] & 0xfc) << 22);
         lsid |= (phyreg[1] & 0x3f) << 16; /* gap count */
         lsid |= (phyreg[2] & 0xc0) << 8; /* max speed */
-        lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
+	if (!hpsb_disable_irm)
+		lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
         /* lsid |= 1 << 11; *//* set contender (hack) */
         lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */
 
@@ -1779,20 +1779,26 @@ static int __devinit add_card(struct pci
                   | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
                   | LINK_CONTROL_RESET_TX    | LINK_CONTROL_RESET_RX);
 
-        if (!lynx->phyic.reg_1394a) {
-                /* attempt to enable contender bit -FIXME- would this work
-                 * elsewhere? */
-                reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
-                reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1);
-        } else {
-                /* set the contender and LCtrl bit in the extended PHY register
-                 * set. (Should check that bis 0,1,2 (=0xE0) is set
-                 * in register 2?)
-                 */
-                i = get_phy_reg(lynx, 4);
-                if (i != -1) set_phy_reg(lynx, 4, i | 0xc0);
-        }
-
+	if (!lynx->phyic.reg_1394a) {
+		if (!hpsb_disable_irm) {
+			/* attempt to enable contender bit -FIXME- would this
+			 * work elsewhere? */
+			reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
+			reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1);
+		}
+	} else {
+		/* set the contender (if appropriate) and LCtrl bit in the
+		 * extended PHY register set. (Should check that PHY_02_EXTENDED
+		 * is set in register 2?)
+		 */
+		i = get_phy_reg(lynx, 4);
+		i |= PHY_04_LCTRL;
+		if (hpsb_disable_irm)
+			i &= !PHY_04_CONTENDER;
+		else
+			i |= PHY_04_CONTENDER;
+		if (i != -1) set_phy_reg(lynx, 4, i);
+	}
 
         if (!skip_eeprom)
         {
_