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 278221 2015-02-04 20:03:57Z arybchik $");
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 SFXGE_MCDI_LOCK(mcdi);
56 KASSERT(mcdi->state != SFXGE_MCDI_UNINITIALIZED,
57 ("MCDI not initialized"));
58
59 while (mcdi->state != SFXGE_MCDI_INITIALIZED)
60 (void)cv_wait_sig(&mcdi->cv, &mcdi->lock);
61 mcdi->state = SFXGE_MCDI_BUSY;
62
63 SFXGE_MCDI_UNLOCK(mcdi);
64}
65
66/* Release ownership of MCDI on request completion. */
67static void
68sfxge_mcdi_release(struct sfxge_mcdi *mcdi)
69{
70 SFXGE_MCDI_LOCK(mcdi);
71 KASSERT((mcdi->state == SFXGE_MCDI_BUSY ||
72 mcdi->state == SFXGE_MCDI_COMPLETED),
73 ("MCDI not busy or task not completed"));
74
75 mcdi->state = SFXGE_MCDI_INITIALIZED;
76 cv_broadcast(&mcdi->cv);
77
78 SFXGE_MCDI_UNLOCK(mcdi);
79}
80
81static void
82sfxge_mcdi_timeout(struct sfxge_softc *sc)
83{
84 device_t dev = sc->dev;
85
86 log(LOG_WARNING, "[%s%d] MC_TIMEOUT", device_get_name(dev),

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

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

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

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