Thread: [Linux1394-cvslog] rev 858 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <ben...@li...> - 2003-04-10 14:45:26
|
Author: bencollins Date: 2003-04-10 10:44:45 -0400 (Thu, 10 Apr 2003) New Revision: 858 Modified: trunk/ohci1394.c trunk/ohci1394.h Log: busReset loop check, forward ported from 2.4 branch Modified: trunk/ohci1394.c ============================================================================== --- trunk/ohci1394.c (original) +++ trunk/ohci1394.c 2003-04-10 10:44:46.000000000 -0400 @@ -80,6 +80,10 @@ * Manfred Weihs <we...@ic...> * . Reworked code for initiating bus resets * (long, short, with or without hold-off) + * + * Nandu Santhi <con...@us...> + * . Added support for nVidia nForce2 onboard Firewire chipset + * */ #include <linux/config.h> @@ -146,7 +150,7 @@ #define OHCI_DMA_FREE(fmt, args...) \ HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ --global_outstanding_dmas, ## args) -u32 global_outstanding_dmas = 0; +static int global_outstanding_dmas = 0; #else #define OHCI_DMA_ALLOC(fmt, args...) #define OHCI_DMA_FREE(fmt, args...) @@ -2293,17 +2297,35 @@ * selfID phase, so we disable busReset interrupts, to * avoid burying the cpu in interrupt requests. */ spin_lock_irqsave(&ohci->event_lock, flags); - reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset); - if (ohci->dev->vendor == PCI_VENDOR_ID_APPLE && - ohci->dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) { - udelay(10); - while(reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { - reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset); + + if (ohci->check_busreset) { + int loop_count = 0; + + udelay(10); + + while (reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { + reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + spin_unlock_irqrestore(&ohci->event_lock, flags); - udelay(10); + udelay(10); spin_lock_irqsave(&ohci->event_lock, flags); - } - } + + /* The loop counter check is to prevent the driver + * from remaining in this state forever. For the + * initial bus reset, the loop continues for ever + * and the system hangs, until some device is plugged-in + * or out manually into a port! The forced reset seems + * to solve this problem. This mainly effects nForce2. */ + if (loop_count > 10000) { + hpsb_reset_bus(host, 1); + DBGMSG(ohci->id, "Detected bus-reset loop. Forced a bus reset!"); + loop_count = 0; + } + + loop_count++; + } + } spin_unlock_irqrestore(&ohci->event_lock, flags); if (!host->in_bus_reset) { DBGMSG(ohci->id, "irq_handler: Bus reset requested"); @@ -2440,6 +2462,8 @@ if (event) PRINT(KERN_ERR, ohci->id, "Unhandled interrupt(s) 0x%08x", event); + + return; } /* Put the buffer back into the dma context */ @@ -3279,6 +3303,18 @@ ohci->selfid_swap = 1; #endif +#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_FW +#define PCI_DEVICE_ID_NVIDIA_NFORCE2_FW 0x006e +#endif + + /* These chipsets require a bit of extra care when checking after + * a busreset. */ + if ((dev->vendor == PCI_VENDOR_ID_APPLE && + dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) || + (dev->vendor == PCI_VENDOR_ID_NVIDIA && + dev->device == PCI_DEVICE_ID_NVIDIA_NFORCE2_FW)) + ohci->check_busreset = 1; + /* We hardwire the MMIO length, since some CardBus adaptors * fail to report the right length. Anyway, the ohci spec * clearly says it's 2kb, so this shouldn't be a problem. */ Modified: trunk/ohci1394.h ============================================================================== --- trunk/ohci1394.h (original) +++ trunk/ohci1394.h 2003-04-10 10:44:47.000000000 -0400 @@ -233,6 +233,9 @@ unsigned int selfid_swap:1; /* Some Apple chipset seem to swap incoming headers for us */ unsigned int no_swap_incoming:1; + + /* Force extra paranoia checking on bus-reset handling */ + unsigned int check_busreset:1; }; static inline int cross_bound(unsigned long addr, unsigned int size) |