Locking changes.

+ Synchronize ath_calibrate() with ATH_LOCK()/ATH_UNLOCK().  Thanks
  to Steve Woodford for suggesting this fix.  This patch stops
  ath(4) from generating messages "hardware error; resetting" while
  Steve's D-Link DWL-AG650 card is operating (kern/28385).  The
  MiniPCI wireless adapter on one of my Soekris boards also operates
  more reliably following this patch.

+ Use ATH_LOCK_IMPL() and family to synchronize access to the
  transmit queue, also.
This commit is contained in:
dyoung 2005-07-03 19:58:16 +00:00
parent f069ffb8c5
commit c1446c092d
2 changed files with 21 additions and 20 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ath.c,v 1.52 2005/07/03 19:44:50 dyoung Exp $ */ /* $NetBSD: ath.c,v 1.53 2005/07/03 19:58:16 dyoung Exp $ */
/*- /*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -41,7 +41,7 @@
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.88 2005/04/12 17:56:43 sam Exp $"); __FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.88 2005/04/12 17:56:43 sam Exp $");
#endif #endif
#ifdef __NetBSD__ #ifdef __NetBSD__
__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.52 2005/07/03 19:44:50 dyoung Exp $"); __KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.53 2005/07/03 19:58:16 dyoung Exp $");
#endif #endif
/* /*
@ -4122,6 +4122,7 @@ ath_calibrate(void *arg)
sc->sc_stats.ast_per_cal++; sc->sc_stats.ast_per_cal++;
ATH_LOCK(sc);
DPRINTF(sc, ATH_DEBUG_CALIBRATE, "%s: channel %u/%x\n", DPRINTF(sc, ATH_DEBUG_CALIBRATE, "%s: channel %u/%x\n",
__func__, sc->sc_curchan.channel, sc->sc_curchan.channelFlags); __func__, sc->sc_curchan.channel, sc->sc_curchan.channelFlags);
@ -4140,6 +4141,7 @@ ath_calibrate(void *arg)
sc->sc_stats.ast_per_calfail++; sc->sc_stats.ast_per_calfail++;
} }
callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc); callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc);
ATH_UNLOCK(sc);
} }
static int static int

View File

@ -49,37 +49,29 @@ typedef struct ath_task {
#define TASK_RUN_OR_ENQUEUE(__task) \ #define TASK_RUN_OR_ENQUEUE(__task) \
((*(__task)->t_func)((__task)->t_context, 1)) ((*(__task)->t_func)((__task)->t_context, 1))
typedef int ath_txq_lock_t;
#define ATH_TXQ_LOCK_INIT(_sc, _tq)
#define ATH_TXQ_LOCK_DESTROY(_tq)
#define ATH_TXQ_LOCK(_tq) \
do { (_tq)->axq_lock = splnet(); } while (0)
#define ATH_TXQ_UNLOCK(_tq) \
do { splx((_tq)->axq_lock); } while (0)
#define ATH_TXQ_LOCK_ASSERT(_tq)
struct ath_lock { struct ath_lock {
int count; int count;
int ipl; int ipl;
}; };
#define ATH_LOCK_INIT_IMPL(_sc, _member) \ #define ATH_LOCK_INIT_IMPL(_type, _member) \
do { (_sc)->_member.count = 0; } while (0) do { (_type)->_member.count = 0; } while (0)
#define ATH_LOCK_IMPL(_sc, _member) \ #define ATH_LOCK_IMPL(_type, _member) \
do { \ do { \
int __s = splnet(); \ int __s = splnet(); \
if ((_sc)->_member.count++ == 0) \ if ((_type)->_member.count++ == 0) \
(_sc)->_member.ipl = __s; \ (_type)->_member.ipl = __s; \
} while (0) } while (0)
#define ATH_UNLOCK_IMPL(_sc, _member) \ #define ATH_UNLOCK_IMPL(_type, _member) \
do { \ do { \
if (--(_sc)->_member.count == 0) \ if (--(_type)->_member.count == 0) \
splx((_sc)->_member.ipl); \ splx((_type)->_member.ipl); \
else { \ else { \
KASSERT((_sc)->_member.count >= 0, \ KASSERT((_type)->_member.count >= 0, \
("%s: no ATH_LOCK holders", __func__)); \ ("%s: no ATH_LOCK holders", __func__)); \
} \ } \
} while (0) } while (0)
typedef struct ath_lock ath_lock_t; typedef struct ath_lock ath_lock_t;
#define ATH_LOCK_INIT(_sc) ATH_LOCK_INIT_IMPL(_sc, sc_mtx) #define ATH_LOCK_INIT(_sc) ATH_LOCK_INIT_IMPL(_sc, sc_mtx)
#define ATH_LOCK_DESTROY(_sc) #define ATH_LOCK_DESTROY(_sc)
@ -87,6 +79,13 @@ typedef struct ath_lock ath_lock_t;
#define ATH_UNLOCK(_sc) ATH_UNLOCK_IMPL(_sc, sc_mtx) #define ATH_UNLOCK(_sc) ATH_UNLOCK_IMPL(_sc, sc_mtx)
#define ATH_LOCK_ASSERT(_sc) #define ATH_LOCK_ASSERT(_sc)
typedef struct ath_lock ath_txq_lock_t;
#define ATH_TXQ_LOCK_INIT(_sc, _tq) ATH_LOCK_INIT_IMPL(_tq, axq_lock)
#define ATH_TXQ_LOCK_DESTROY(_tq)
#define ATH_TXQ_LOCK(_tq) ATH_LOCK_IMPL(_tq, axq_lock)
#define ATH_TXQ_UNLOCK(_tq) ATH_UNLOCK_IMPL(_tq, axq_lock)
#define ATH_TXQ_LOCK_ASSERT(_tq)
typedef struct ath_lock ath_txbuf_lock_t; typedef struct ath_lock ath_txbuf_lock_t;
#define ATH_TXBUF_LOCK_INIT(_sc) ATH_LOCK_INIT_IMPL(_sc, sc_txbuflock) #define ATH_TXBUF_LOCK_INIT(_sc) ATH_LOCK_INIT_IMPL(_sc, sc_txbuflock)
#define ATH_TXBUF_LOCK_DESTROY(_sc) #define ATH_TXBUF_LOCK_DESTROY(_sc)