Thread: [Madwifi-devel] Advice needed on how to submit fix for arm xscale be
Status: Beta
Brought to you by:
otaku
From: Michael T. <mik...@ap...> - 2007-04-26 19:20:45
|
There seem to be several bugs related to arm_xscale_be systems that all result in the same type of mysterious "bad mode" aborts. I found a workaround by disabling interrupts during register reads and writes, but it occurs to me that I might just be suppressing an actual error. It doesn't look like that, however, from all the various stack traces we were seeing. Also, and the driver is working well interrupts disabled during the register read/write ops. I suspect a problem with preemption and ixp4xx_pci_read_errata/ixp4xx_pci_read_no_errata... can anyone give me an education? :-D Thanks, Mike |
From: Michael T. <mik...@ap...> - 2007-04-27 16:30:55
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type"> <title></title> </head> <body bgcolor="#ffffff" text="#000000"> <tt>No, sorry. I wasn't clear enough in my post on the context.<br> <br> There are a rash of bugs filed for IXP46x and related chips in big endian mode filed against MadWifi.<br> <br> I've was chasing them down when I discovered that disabling interrupts in ath_hal_reg_read and ath_hal_reg_write solved them.<br> <br> I've got no problems elsewhere, but admittedly all my PCI devices are Atheros devices. Since others are experiencing the same problems I thought I should post the workaround that worked for me.<br> <br> I just don't understand why this change would fix most of the "bad mode" oops that happen in madwifi on this platform.<br> <br> With that missing bit of key information, perhaps it makes more sense and you have an idea?<br> <br> Here's the patch I used to fix most IXP465 crashes of MadWifi. <br> <br> It's "wrong" because I don't think this problem necessarily affects all platforms, although it was introduced when the _OS_REG_WRITE and _OS_REG_READ were rewritten for big Endian systems... it's not clear that this crash happens for all BE systems.<br> <br> Here's _OS_REG_READ for BE systems:<br> <br> #define _OS_REG_READ(_ah, _reg) \<br> ((0x4000 <= (_reg) && (_reg) < 0x5000) ? \<br> readl((void __force __iomem *)((_ah)->ah_sh + (_reg))) : \<br> __raw_readl((void __force __iomem *)((_ah)->ah_sh + (_reg))))<br> <br> Seems like something caused by an interrupt is corrupting the values used for _ah or _reg somehow, resulting in a bus error or something. I just don't know enough aboug the kernel yet to diagnose it further.<br> <br> Any tips?<br> <br> <br> --- BUILD/madwifi/ath_hal/ah_os.h.clean 2007-04-11 13:02:28.000000000 -0700<br> +++ BUILD/madwifi/ath_hal/ah_os.h 2007-04-11 13:03:03.000000000 -0700<br> @@ -162,7 +162,7 @@ extern u_int32_t __ahdecl ath_hal_getupt<br> readl((void __force __iomem *)((_ah)->ah_sh + (_reg)))<br> #endif /* AH_BYTE_ORDER */<br> <br> -#if defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || defined(AH_DEBUG_ALQ)<br> +#if defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || defined(AH_DEBUG_ALQ) || (AH_BYTE_ORDER == AH_BIG_ENDIAN)<br> /* use functions to do register operations */<br> #define OS_REG_WRITE(_ah, _reg, _val) ath_hal_reg_write(_ah, _reg, _val)<br> #define OS_REG_READ(_ah, _reg) ath_hal_reg_read(_ah, _reg)<br> --- BUILD/madwifi/ath_hal/ah_os.c.clean 2007-04-11 13:24:40.000000000 -0700<br> +++ BUILD/madwifi/ath_hal/ah_os.c 2007-04-11 13:32:25.000000000 -0700<br> @@ -250,11 +250,11 @@ ath_hal_alq_get(struct ath_hal *ah)<br> void __ahdecl<br> ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)<br> {<br> - if (ath_hal_alq) {<br> unsigned long flags;<br> + local_irq_save(flags);<br> + if (ath_hal_alq) {<br> struct ale *ale;<br> <br> - local_irq_save(flags);<br> ale = ath_hal_alq_get(ah);<br> if (ale) {<br> struct athregrec *r = (struct athregrec *) ale->ae_data;<br> @@ -263,23 +263,23 @@ ath_hal_reg_write(struct ath_hal *ah, u_<br> r->val = val;<br> alq_post(ath_hal_alq, ale);<br> }<br> - local_irq_restore(flags);<br> }<br> _OS_REG_WRITE(ah, reg, val);<br> + local_irq_restore(flags);<br> }<br> EXPORT_SYMBOL(ath_hal_reg_write);<br> <br> u_int32_t __ahdecl<br> ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)<br> {<br> + unsigned long flags;<br> + local_irq_save(flags);<br> u_int32_t val;<br> <br> val = _OS_REG_READ(ah, reg);<br> if (ath_hal_alq) {<br> - unsigned long flags;<br> struct ale *ale;<br> <br> - local_irq_save(flags);<br> ale = ath_hal_alq_get(ah);<br> if (ale) {<br> struct athregrec *r = (struct athregrec *) ale->ae_data;<br> @@ -288,8 +288,8 @@ ath_hal_reg_read(struct ath_hal *ah, u_i<br> r->val = val;<br> alq_post(ath_hal_alq, ale);<br> }<br> - local_irq_restore(flags);<br> }<br> + local_irq_restore(flags);<br> return val;<br> }<br> EXPORT_SYMBOL(ath_hal_reg_read);<br> @@ -314,7 +314,7 @@ OS_MARK(struct ath_hal *ah, u_int id, u_<br> }<br> }<br> EXPORT_SYMBOL(OS_MARK);<br> -#elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)<br> +#elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || (AH_BYTE_ORDER == AH_BIG_ENDIAN)<br> /*<br> * Memory-mapped device register read/write. These are here<br> * as routines when debugging support is enabled and/or when<br> @@ -328,20 +328,27 @@ EXPORT_SYMBOL(OS_MARK);<br> void __ahdecl<br> ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val)<br> {<br> + unsigned long flags;<br> + local_irq_save(flags);<br> #ifdef AH_DEBUG<br> if (ath_hal_debug > 1)<br> ath_hal_printf(ah, "WRITE 0x%x <= 0x%x\n", reg, val);<br> #endif<br> + <br> _OS_REG_WRITE(ah, reg, val);<br> + local_irq_restore(flags);<br> }<br> EXPORT_SYMBOL(ath_hal_reg_write);<br> <br> u_int32_t __ahdecl<br> ath_hal_reg_read(struct ath_hal *ah, u_int reg)<br> {<br> + unsigned long flags;<br> u_int32_t val;<br> + local_irq_save(flags);<br> <br> val = _OS_REG_READ(ah, reg);<br> + local_irq_restore(flags);<br> #ifdef AH_DEBUG<br> if (ath_hal_debug > 1)<br> ath_hal_printf(ah, "READ 0x%x => 0x%x\n", reg, val);<br> <br> <br> - M<br> <br> <br> </tt>Pavel Roskin wrote: <blockquote cite="mid1177655725.7843.6.camel@dv" type="cite"> <pre wrap="">On Thu, 2007-04-26 at 12:20 -0700, Michael Taylor wrote: </pre> <blockquote type="cite"> <pre wrap="">There seem to be several bugs related to arm_xscale_be systems that all result in the same type of mysterious "bad mode" aborts. I found a workaround by disabling interrupts during register reads and writes, but it occurs to me that I might just be suppressing an actual error. It doesn't look like that, however, from all the various stack traces we were seeing. Also, and the driver is working well interrupts disabled during the register read/write ops. I suspect a problem with preemption and ixp4xx_pci_read_errata/ixp4xx_pci_read_no_errata... can anyone give me an education? :-D </pre> </blockquote> <pre wrap=""><!----> This was posted to <a class="moz-txt-link-abbreviated" href="mailto:mad...@li...">mad...@li...</a> I'm almost sure you meant to post it elsewhere. </pre> </blockquote> </body> </html> |