Deleted Added
sdiff udiff text old ( 227569 ) new ( 278221 )
full compact
1/*-
2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_mcdi.c 227569 2011-11-16 17:11:13Z philip $");
32
33#include <sys/param.h>
34#include <sys/condvar.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>
37#include <sys/proc.h>
38#include <sys/syslog.h>
39#include <sys/taskqueue.h>

--- 7 unchanged lines hidden (view full) ---

47#define SFXGE_MCDI_POLL_INTERVAL_MIN 10 /* 10us in 1us units */
48#define SFXGE_MCDI_POLL_INTERVAL_MAX 100000 /* 100ms in 1us units */
49#define SFXGE_MCDI_WATCHDOG_INTERVAL 10000000 /* 10s in 1us units */
50
51/* Acquire exclusive access to MCDI for the duration of a request. */
52static void
53sfxge_mcdi_acquire(struct sfxge_mcdi *mcdi)
54{
55
56 mtx_lock(&mcdi->lock);
57 KASSERT(mcdi->state != SFXGE_MCDI_UNINITIALIZED,
58 ("MCDI not initialized"));
59
60 while (mcdi->state != SFXGE_MCDI_INITIALIZED)
61 (void)cv_wait_sig(&mcdi->cv, &mcdi->lock);
62 mcdi->state = SFXGE_MCDI_BUSY;
63
64 mtx_unlock(&mcdi->lock);
65}
66
67/* Release ownership of MCDI on request completion. */
68static void
69sfxge_mcdi_release(struct sfxge_mcdi *mcdi)
70{
71
72 mtx_lock(&mcdi->lock);
73 KASSERT((mcdi->state == SFXGE_MCDI_BUSY ||
74 mcdi->state == SFXGE_MCDI_COMPLETED),
75 ("MCDI not busy or task not completed"));
76
77 mcdi->state = SFXGE_MCDI_INITIALIZED;
78 cv_broadcast(&mcdi->cv);
79
80 mtx_unlock(&mcdi->lock);
81}
82
83static void
84sfxge_mcdi_timeout(struct sfxge_softc *sc)
85{
86 device_t dev = sc->dev;
87
88 log(LOG_WARNING, "[%s%d] MC_TIMEOUT", device_get_name(dev),

--- 66 unchanged lines hidden (view full) ---

155sfxge_mcdi_ev_cpl(void *arg)
156{
157 struct sfxge_softc *sc;
158 struct sfxge_mcdi *mcdi;
159
160 sc = (struct sfxge_softc *)arg;
161 mcdi = &sc->mcdi;
162
163 mtx_lock(&mcdi->lock);
164 KASSERT(mcdi->state == SFXGE_MCDI_BUSY, ("MCDI not busy"));
165 mcdi->state = SFXGE_MCDI_COMPLETED;
166 cv_broadcast(&mcdi->cv);
167 mtx_unlock(&mcdi->lock);
168}
169
170static void
171sfxge_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
172{
173 struct sfxge_softc *sc;
174 device_t dev;
175

--- 22 unchanged lines hidden (view full) ---

198
199 enp = sc->enp;
200 mcdi = &sc->mcdi;
201 emtp = &mcdi->transport;
202
203 KASSERT(mcdi->state == SFXGE_MCDI_UNINITIALIZED,
204 ("MCDI already initialized"));
205
206 mtx_init(&mcdi->lock, "sfxge_mcdi", NULL, MTX_DEF);
207
208 mcdi->state = SFXGE_MCDI_INITIALIZED;
209
210 emtp->emt_context = sc;
211 emtp->emt_execute = sfxge_mcdi_execute;
212 emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl;
213 emtp->emt_exception = sfxge_mcdi_exception;
214
215 cv_init(&mcdi->cv, "sfxge_mcdi");
216
217 if ((rc = efx_mcdi_init(enp, emtp)) != 0)
218 goto fail;
219
220 return (0);
221
222fail:
223 mtx_destroy(&mcdi->lock);
224 mcdi->state = SFXGE_MCDI_UNINITIALIZED;
225 return (rc);
226}
227
228void
229sfxge_mcdi_fini(struct sfxge_softc *sc)
230{
231 struct sfxge_mcdi *mcdi;
232 efx_nic_t *enp;
233 efx_mcdi_transport_t *emtp;
234
235 enp = sc->enp;
236 mcdi = &sc->mcdi;
237 emtp = &mcdi->transport;
238
239 mtx_lock(&mcdi->lock);
240 KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
241 ("MCDI not initialized"));
242
243 efx_mcdi_fini(enp);
244 bzero(emtp, sizeof(*emtp));
245
246 cv_destroy(&mcdi->cv);
247 mtx_unlock(&mcdi->lock);
248
249 mtx_destroy(&mcdi->lock);
250}