From: Jim C. <jim...@gm...> - 2012-05-08 17:14:50
|
also rewrap comments Signed-off-by: Jim Cromie <jim...@gm...> --- mem-inlines.h | 141 +++++++++++++++++++++++++++++++------------------------- 1 files changed, 78 insertions(+), 63 deletions(-) diff --git a/mem-inlines.h b/mem-inlines.h index fbebdb7..36cbfa9 100644 --- a/mem-inlines.h +++ b/mem-inlines.h @@ -1,64 +1,75 @@ #ifndef _MEM_INLINES_H_ #define _MEM_INLINES_H_ +/* currently need this even for no-mem builds, as it contains the + * locking elements used in merge.c. TBD whether its worth + * repartitioning to achieve this + */ +#if defined(CONFIG_ACX_MAC80211_MEM) || 1 + /* * Locking in mem * ================================================== */ /* -* Locking in mem is more complex as for pci, because the different data-access -* functions below need to be protected against incoming interrupts. -* -* Data-access on the mem device is always going in serveral, none-atomic steps, -* involving 2 or more register writes (e.g. ACX_SLV_REG_ADDR, ACX_SLV_REG_DATA). -* -* If an interrupt is serviced while a data-access function is ongoing, this -* may give access interference with by the involved operations, since the -* irq routine is also using the same data-access functions. -* -* In case of interference, this often manifests during driver operations as -* failure of device cmds and subsequent hanging of the device. It especially -* appeared during sw-scans while a connection was up. -* -* For this reason, irqs shall be off while data access functions are executed, -* and for this we'll use the acx-spinlock. -* -* In pci we don't have this problem, because all data-access functions are -* atomic enough and we use dma (and the sw-scan problem is also not observed in -* pci, which indicates confirmation). -* -* Apart from this, the pure acx-sem locking is already coordinating accesses -* well enough, that simple driver operation without inbetween scans work without -* problems. -* -* Different locking approaches a possible to solves this (e.g. fine vs -* coarse-grained). -* -* The chosen approach is: -* -* 1) Mem.c data-access functions contain all a check to insure, they are executed -* under the acx-spinlock. -* => This is the red line that tells, if something needs coverage. -* -* 2) The scope of acx-spinlocking is local, in this case here only to mem.c. -* All common.c functions are already protected by the sem. -* -* 3) In order to consolidate locking calls and also to account for the logic -* of the various write_flush() calls around, locking in mem should be: -* -* a) as coarse-grained as possible, and ... -* -* b) ... as fine-grained as required. Basically that means, that before -* functions, that sleep, unlocking needs to be done. And locking is taken up -* again inside the sleeping function. Specifically the cmd-functions are used -* in this path. -* -* Once stable, the locking checks in the data-access functions could be #defined -* away. Mem.c is anyway more used two smaller cpus (pxa UP e.g.), so the implied -* runtime constraints by the lock won't take much effect. -* -*/ + * Locking in mem is more complex as for pci, because the different + * data-access functions below need to be protected against incoming + * interrupts. + * + * Data-access on the mem device is always going in serveral, + * none-atomic steps, involving 2 or more register writes + * (e.g. ACX_SLV_REG_ADDR, ACX_SLV_REG_DATA). + * + * If an interrupt is serviced while a data-access function is + * ongoing, this may give access interference with by the involved + * operations, since the irq routine is also using the same + * data-access functions. + * + * In case of interference, this often manifests during driver + * operations as failure of device cmds and subsequent hanging of the + * device. It especially appeared during sw-scans while a connection + * was up. + * + * For this reason, irqs shall be off while data access functions are + * executed, and for this we'll use the acx-spinlock. + * + * In pci we don't have this problem, because all data-access + * functions are atomic enough and we use dma (and the sw-scan problem + * is also not observed in pci, which indicates confirmation). + * + * Apart from this, the pure acx-sem locking is already coordinating + * accesses well enough, that simple driver operation without + * inbetween scans work without problems. + * + * Different locking approaches a possible to solves this (e.g. fine + * vs coarse-grained). + * + * The chosen approach is: + * + * 1) Mem.c data-access functions contain all a check to insure, they + * are executed under the acx-spinlock. => This is the red line that + * tells, if something needs coverage. + * + * 2) The scope of acx-spinlocking is local, in this case here only to + * mem.c. All common.c functions are already protected by the sem. + * + * 3) In order to consolidate locking calls and also to account for + * the logic of the various write_flush() calls around, locking in mem + * should be: + * + * a) as coarse-grained as possible, and ... + * + * b) ... as fine-grained as required. Basically that means, that + * before functions, that sleep, unlocking needs to be done. And + * locking is taken up again inside the sleeping + * function. Specifically the cmd-functions are used in this path. + * + * Once stable, the locking checks in the data-access functions could + * be #defined away. Mem.c is anyway more used two smaller cpus (pxa + * UP e.g.), so the implied runtime constraints by the lock won't take + * much effect. + */ /* These are used in many mem.c funcs, including those which should be * merged with their pci counterparts. @@ -231,16 +242,17 @@ INLINE_IO void write_reg8(acx_device_t *adev, unsigned int offset, u8 val) writeb(val, (u8 *) (adev->iobase + ACX_SLV_REG_DATA)); } -/* Handle PCI posting properly: - * Make sure that writes reach the adapter in case they require to be executed - * *before* the next write, by reading a random (and safely accessible) register. - * This call has to be made if there is no read following (which would flush the data - * to the adapter), yet the written data has to reach the adapter immediately. */ +/* Handle PCI posting properly: Make sure that writes reach the + * adapter in case they require to be executed *before* the next + * write, by reading a random (and safely accessible) register. This + * call has to be made if there is no read following (which would + * flush the data to the adapter), yet the written data has to reach + * the adapter immediately. */ INLINE_IO void write_flush(acx_device_t *adev) { /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */ - /* faster version (accesses the first register, IO_ACX_SOFT_RESET, - * which should also be safe): */ + /* faster version (accesses the first register, + * IO_ACX_SOFT_RESET, which should also be safe): */ ACXMEM_WARN_NOT_SPIN_LOCKED; (void) acx_readl(adev->iobase); } @@ -270,8 +282,8 @@ INLINE_IO void clear_regbits(acx_device_t *adev, unsigned int offset, u32 bits) } /* - * Copy from PXA memory to the ACX memory. This assumes both the PXA and ACX - * addresses are 32 bit aligned. Count is in bytes. + * Copy from PXA memory to the ACX memory. This assumes both the PXA + * and ACX addresses are 32 bit aligned. Count is in bytes. */ INLINE_IO void write_slavemem32(acx_device_t *adev, u32 slave_address, u32 val) { @@ -306,7 +318,8 @@ INLINE_IO void write_slavemem8(acx_device_t *adev, u32 slave_address, u8 val) ACXMEM_WARN_NOT_SPIN_LOCKED; /* - * Get the word containing the target address and the byte offset in that word. + * Get the word containing the target address and the byte + * offset in that word. */ base = slave_address & ~3; offset = (slave_address & 3) * 8; @@ -348,7 +361,8 @@ INLINE_IO void write_slavemem16(acx_device_t *adev, u32 slave_address, u16 val) ACXMEM_WARN_NOT_SPIN_LOCKED; /* - * Get the word containing the target address and the byte offset in that word. + * Get the word containing the target address and the byte + * offset in that word. */ base = slave_address & ~3; offset = (slave_address & 3) * 8; @@ -381,4 +395,5 @@ INLINE_IO u16 read_slavemem16(acx_device_t *adev, u32 slave_address) return val; } +#endif /* CONFIG_ACX_MAC80211_MEM */ #endif /* _MEM_INLINES_H_ */ -- 1.7.8.1 |