Re: OHCI driver grabs IRQ too early.
Brought to you by:
aeb,
bencollins
From: Daniel K. <dan...@st...> - 2000-05-14 16:35:55
|
On Sun, 14 May 2000, Sebastien Rougeaux wrote: > Thanks for the patch. Any luck with the SONY chip ? Not as much as I'd like to. As I wrote on Friday, there's clearly life on the bus but that's about all I see. Anyway, I've found the cause - or a workaround at least - for the OHCI module hanging my machine when I insmod it the second time: First of all, stop_context() gives me runaway loops upon rmmod. On the next insmod, the chip will lock the machine (well, the PCI bus most probably) when isoRecvIntMask is set to 0x1. I'm not sure why, but I suspect that setting the mask activates the context. The associated program however is not yet initialized. So once again I moved a bit of code around to locations that looked sane to me. I also made sure all iso recv interrupts are cleared on initialization. reg_read()/reg_write() contain some #ifdef'd code to track down such PCI lock ups; maybe someone will find this useful one day. Regards, Daniel. --[snip]-- Index: ohci1394.c =================================================================== RCS file: /cvsroot/linux1394/ieee1394/ohci1394.c,v retrieving revision 1.29 diff -u -r1.29 ohci1394.c --- ohci1394.c 2000/05/14 02:21:11 1.29 +++ ohci1394.c 2000/05/14 16:13:27 @@ -1088,8 +1088,8 @@ reg_write(ohci, OHCI1394_LinkControlSet, 0x00300000); /* Clear interrupt registers */ - reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); /* Set up self-id dma buffer */ reg_write(ohci, OHCI1394_SelfIDBuffer, @@ -1156,6 +1156,18 @@ /* Clear the interrupt mask */ reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff); + + /* Initialize AR dma */ + initialize_dma_rcv_ctx(ohci->ar_req_context); + initialize_dma_rcv_ctx(ohci->ar_resp_context); + + /* Initialize AT dma */ + initialize_dma_trm_ctx(ohci->at_req_context); + initialize_dma_trm_ctx(ohci->at_resp_context); + + /* Initialize IR dma */ + initialize_dma_rcv_ctx(ohci->ir_context); /* Set up isoRecvIntMask to generate interrupts for context 0 (thanks to Michael Greger for seeing that I forgot this) */ @@ -1197,17 +1209,6 @@ /* Enable link */ reg_write(ohci, OHCI1394_HCControlSet, 0x00020000); - - /* Initialize AR dma */ - initialize_dma_rcv_ctx(ohci->ar_req_context); - initialize_dma_rcv_ctx(ohci->ar_resp_context); - - /* Initialize AT dma */ - initialize_dma_trm_ctx(ohci->at_req_context); - initialize_dma_trm_ctx(ohci->at_resp_context); - - /* Initialize IR dma */ - initialize_dma_rcv_ctx(ohci->ir_context); return 1; } Index: ohci1394.h =================================================================== RCS file: /cvsroot/linux1394/ieee1394/ohci1394.h,v retrieving revision 1.15 diff -u -r1.15 ohci1394.h --- ohci1394.h 2000/05/14 02:21:11 1.15 +++ ohci1394.h 2000/05/14 16:13:27 @@ -221,12 +221,38 @@ */ inline static void reg_write(const struct ti_ohci *ohci, int offset, u32 data) { +#ifdef OHCI1394_EXCESSIVE_DEBUG + printk(KERN_CRIT "ohci%d: Writing 0x%08x to register 0x%04x.\n", + ohci->id, data, offset); + /* To track down a lockup, other processes must be given a + * chance to display the printk output! + */ + if (!in_interrupt()) + schedule(); writel(data, ohci->registers + offset); + printk(KERN_CRIT "ohci%d: Write done.\n", ohci->id); +#else + writel(data, ohci->registers + offset); +#endif } inline static u32 reg_read(const struct ti_ohci *ohci, int offset) { - return readl(ohci->registers + offset); +#ifdef OHCI1394_EXCESSIVE_DEBUG + u32 tmp; + printk(KERN_CRIT "ohci%d: Reading from register 0x%04x.\n", + ohci->id, offset); + /* To track down a lockup, other processes must be given a + * chance to display the printk output! + */ + if (!in_interrupt()) + schedule(); + tmp = readl(ohci->registers + offset); + printk(KERN_CRIT "ohci%d: Read 0x%08x.\n", ohci->id, tmp); + return tmp; +#else + return readl(ohci->registers + offset); +#endif } /* This structure is not properly initialized ... it is taken from |