From: Jody McIntyre 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 Signed-off-by: Andrew Morton --- 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 2005-01-23 14:47:35.361821352 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394_core.c 2005-01-23 14:47:35.373819528 -0800 @@ -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 2005-01-23 14:47:35.362821200 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394_core.h 2005-01-23 14:47:35.374819376 -0800 @@ -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 2005-01-23 14:47:35.363821048 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394.h 2005-01-23 14:47:35.374819376 -0800 @@ -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 #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 2005-01-23 14:47:35.365820744 -0800 +++ 25-akpm/drivers/ieee1394/nodemgr.c 2005-01-23 14:47:35.376819072 -0800 @@ -23,6 +23,7 @@ #include "ieee1394_types.h" #include "ieee1394.h" +#include "ieee1394_core.h" #include "hosts.h" #include "ieee1394_transactions.h" #include "highlevel.h" @@ -1381,6 +1382,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; @@ -1431,6 +1436,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 2005-01-23 14:47:35.367820440 -0800 +++ 25-akpm/drivers/ieee1394/ohci1394.c 2005-01-23 14:47:35.378818768 -0800 @@ -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 2005-01-23 14:47:35.369820136 -0800 +++ 25-akpm/drivers/ieee1394/pcilynx.c 2005-01-23 14:47:35.380818464 -0800 @@ -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) { _