diff options
author | arybchik <arybchik@FreeBSD.org> | 2015-12-11 07:20:33 +0000 |
---|---|---|
committer | arybchik <arybchik@FreeBSD.org> | 2015-12-11 07:20:33 +0000 |
commit | ebdff42c4262d4c9bcf29831a941e6c80fa830cb (patch) | |
tree | 8bff3b6534b649c75db4a10fe5170f03c78bd531 | |
parent | 610d610a7734cc4cac23ce3d9e604108391dba8c (diff) | |
download | FreeBSD-src-ebdff42c4262d4c9bcf29831a941e6c80fa830cb.zip FreeBSD-src-ebdff42c4262d4c9bcf29831a941e6c80fa830cb.tar.gz |
sfxge: unify MCDI response polling
Submitted by: Andy Moreton <amoreton at solarflare.com>
Reviewed by: philip
Sponsored by: Solarflare Communications, Inc.
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D4496
-rw-r--r-- | sys/dev/sfxge/common/efx_impl.h | 4 | ||||
-rw-r--r-- | sys/dev/sfxge/common/efx_mcdi.c | 77 | ||||
-rw-r--r-- | sys/dev/sfxge/common/hunt_impl.h | 8 | ||||
-rw-r--r-- | sys/dev/sfxge/common/hunt_mcdi.c | 55 | ||||
-rw-r--r-- | sys/dev/sfxge/common/siena_impl.h | 8 | ||||
-rw-r--r-- | sys/dev/sfxge/common/siena_mcdi.c | 65 |
6 files changed, 78 insertions, 139 deletions
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h index b5729b0..502fc78 100644 --- a/sys/dev/sfxge/common/efx_impl.h +++ b/sys/dev/sfxge/common/efx_impl.h @@ -456,12 +456,12 @@ typedef struct efx_mcdi_ops_s { efx_rc_t (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *); void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *, unsigned int, boolean_t, boolean_t); - boolean_t (*emco_request_poll)(efx_nic_t *); void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *); efx_rc_t (*emco_poll_reboot)(efx_nic_t *); + boolean_t (*emco_poll_response)(efx_nic_t *); + void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t); void (*emco_fini)(efx_nic_t *); efx_rc_t (*emco_feature_supported)(efx_nic_t *, efx_mcdi_feature_id_t, boolean_t *); - void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t); } efx_mcdi_ops_t; typedef struct efx_mcdi_s { diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c index 9c022cf..a5c4d52 100644 --- a/sys/dev/sfxge/common/efx_mcdi.c +++ b/sys/dev/sfxge/common/efx_mcdi.c @@ -46,12 +46,12 @@ __FBSDID("$FreeBSD$"); static efx_mcdi_ops_t __efx_mcdi_siena_ops = { siena_mcdi_init, /* emco_init */ siena_mcdi_request_copyin, /* emco_request_copyin */ - siena_mcdi_request_poll, /* emco_request_poll */ siena_mcdi_request_copyout, /* emco_request_copyout */ siena_mcdi_poll_reboot, /* emco_poll_reboot */ + siena_mcdi_poll_response, /* emco_poll_response */ + siena_mcdi_read_response, /* emco_read_response */ siena_mcdi_fini, /* emco_fini */ siena_mcdi_feature_supported, /* emco_feature_supported */ - siena_mcdi_read_response, /* emco_read_response */ }; #endif /* EFSYS_OPT_SIENA */ @@ -61,12 +61,12 @@ static efx_mcdi_ops_t __efx_mcdi_siena_ops = { static efx_mcdi_ops_t __efx_mcdi_hunt_ops = { hunt_mcdi_init, /* emco_init */ hunt_mcdi_request_copyin, /* emco_request_copyin */ - hunt_mcdi_request_poll, /* emco_request_poll */ hunt_mcdi_request_copyout, /* emco_request_copyout */ hunt_mcdi_poll_reboot, /* emco_poll_reboot */ + hunt_mcdi_poll_response, /* emco_poll_response */ + hunt_mcdi_read_response, /* emco_read_response */ hunt_mcdi_fini, /* emco_fini */ hunt_mcdi_feature_supported, /* emco_feature_supported */ - hunt_mcdi_read_response, /* emco_read_response */ }; #endif /* EFSYS_OPT_HUNTINGTON */ @@ -189,7 +189,7 @@ efx_mcdi_request_copyin( emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch); } -static void __unused +static void efx_mcdi_request_copyout( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp) @@ -210,6 +210,17 @@ efx_mcdi_poll_reboot( return (rc); } +static boolean_t +efx_mcdi_poll_response( + __in efx_nic_t *enp) +{ + efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop; + boolean_t available; + + available = emcop->emco_poll_response(enp); + return (available); +} + static void efx_mcdi_read_response( __in efx_nic_t *enp, @@ -389,19 +400,63 @@ fail1: efx_mcdi_request_poll( __in efx_nic_t *enp) { - efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop; - boolean_t completed; + efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); + efx_mcdi_req_t *emrp; + int state; + efx_rc_t rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); - completed = B_FALSE; + /* Serialise against post-watchdog efx_mcdi_ev* */ + EFSYS_LOCK(enp->en_eslp, state); + + EFSYS_ASSERT(emip->emi_pending_req != NULL); + EFSYS_ASSERT(!emip->emi_ev_cpl); + emrp = emip->emi_pending_req; + + /* Check for reboot atomically w.r.t efx_mcdi_request_start */ + if (emip->emi_poll_cnt++ == 0) { + if ((rc = efx_mcdi_poll_reboot(enp)) != 0) { + emip->emi_pending_req = NULL; + EFSYS_UNLOCK(enp->en_eslp, state); + goto fail1; + } + } + + /* Check if a response is available */ + if (efx_mcdi_poll_response(enp) == B_FALSE) { + EFSYS_UNLOCK(enp->en_eslp, state); + return (B_FALSE); + } + + /* Read the response header */ + efx_mcdi_read_response_header(enp, emrp); + + /* Request complete */ + emip->emi_pending_req = NULL; + + EFSYS_UNLOCK(enp->en_eslp, state); + + if ((rc = emrp->emr_rc) != 0) + goto fail2; + + efx_mcdi_request_copyout(enp, emrp); + return (B_TRUE); + +fail2: + if (!emrp->emr_quiet) + EFSYS_PROBE(fail2); +fail1: + if (!emrp->emr_quiet) + EFSYS_PROBE1(fail1, efx_rc_t, rc); - if (emcop != NULL && emcop->emco_request_poll != NULL) - completed = emcop->emco_request_poll(enp); + /* Reboot/Assertion */ + if (rc == EIO || rc == EINTR) + efx_mcdi_raise_exception(enp, emrp, rc); - return (completed); + return (B_TRUE); } __checkReturn boolean_t diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h index 7f29fb0..49a1244 100644 --- a/sys/dev/sfxge/common/hunt_impl.h +++ b/sys/dev/sfxge/common/hunt_impl.h @@ -263,6 +263,10 @@ hunt_mcdi_request_copyin( __in boolean_t ev_cpl, __in boolean_t new_epoch); +extern __checkReturn boolean_t +hunt_mcdi_poll_response( + __in efx_nic_t *enp); + extern void hunt_mcdi_read_response( __in efx_nic_t *enp, @@ -270,10 +274,6 @@ hunt_mcdi_read_response( __in size_t offset, __in size_t length); -extern __checkReturn boolean_t -hunt_mcdi_request_poll( - __in efx_nic_t *enp); - extern void hunt_mcdi_request_copyout( __in efx_nic_t *enp, diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c index d5f458b..2e61e74 100644 --- a/sys/dev/sfxge/common/hunt_mcdi.c +++ b/sys/dev/sfxge/common/hunt_mcdi.c @@ -268,7 +268,7 @@ hunt_mcdi_request_copyout( #endif /* EFSYS_OPT_MCDI_LOGGING */ } -static __checkReturn boolean_t + __checkReturn boolean_t hunt_mcdi_poll_response( __in efx_nic_t *enp) { @@ -299,59 +299,6 @@ hunt_mcdi_read_response( } } - __checkReturn boolean_t -hunt_mcdi_request_poll( - __in efx_nic_t *enp) -{ - efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); - efx_mcdi_req_t *emrp; - int state; - efx_rc_t rc; - - EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON); - - /* Serialise against post-watchdog efx_mcdi_ev* */ - EFSYS_LOCK(enp->en_eslp, state); - - EFSYS_ASSERT(emip->emi_pending_req != NULL); - EFSYS_ASSERT(!emip->emi_ev_cpl); - emrp = emip->emi_pending_req; - - /* Check if a response is available */ - if (hunt_mcdi_poll_response(enp) == B_FALSE) { - EFSYS_UNLOCK(enp->en_eslp, state); - return (B_FALSE); - } - - /* Read the response header */ - efx_mcdi_read_response_header(enp, emrp); - - /* Request complete */ - emip->emi_pending_req = NULL; - - /* Ensure stale MCDI requests fail after an MC reboot. */ - emip->emi_new_epoch = B_FALSE; - - EFSYS_UNLOCK(enp->en_eslp, state); - - if ((rc = emrp->emr_rc) != 0) - goto fail1; - - hunt_mcdi_request_copyout(enp, emrp); - goto out; - -fail1: - if (!emrp->emr_quiet) - EFSYS_PROBE1(fail1, efx_rc_t, rc); - - /* Reboot/Assertion */ - if (rc == EIO || rc == EINTR) - efx_mcdi_raise_exception(enp, emrp, rc); - -out: - return (B_TRUE); -} - efx_rc_t hunt_mcdi_poll_reboot( __in efx_nic_t *enp) diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h index 149efcb..0433edb 100644 --- a/sys/dev/sfxge/common/siena_impl.h +++ b/sys/dev/sfxge/common/siena_impl.h @@ -121,6 +121,10 @@ siena_mcdi_request_copyin( __in boolean_t ev_cpl, __in boolean_t new_epoch); +extern __checkReturn boolean_t +siena_mcdi_poll_response( + __in efx_nic_t *enp); + extern void siena_mcdi_read_response( __in efx_nic_t *enp, @@ -128,10 +132,6 @@ siena_mcdi_read_response( __in size_t offset, __in size_t length); -extern __checkReturn boolean_t -siena_mcdi_request_poll( - __in efx_nic_t *enp); - extern void siena_mcdi_request_copyout( __in efx_nic_t *enp, diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c index a4f64c2..a350598 100644 --- a/sys/dev/sfxge/common/siena_mcdi.c +++ b/sys/dev/sfxge/common/siena_mcdi.c @@ -180,7 +180,7 @@ siena_mcdi_poll_reboot( #endif } -static __checkReturn boolean_t +extern __checkReturn boolean_t siena_mcdi_poll_response( __in efx_nic_t *enp) { @@ -218,69 +218,6 @@ siena_mcdi_read_response( } } - __checkReturn boolean_t -siena_mcdi_request_poll( - __in efx_nic_t *enp) -{ - efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); - efx_mcdi_req_t *emrp; - int state; - efx_rc_t rc; - - EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); - - /* Serialise against post-watchdog efx_mcdi_ev* */ - EFSYS_LOCK(enp->en_eslp, state); - - EFSYS_ASSERT(emip->emi_pending_req != NULL); - EFSYS_ASSERT(!emip->emi_ev_cpl); - emrp = emip->emi_pending_req; - - /* Check for reboot atomically w.r.t efx_mcdi_request_start */ - if (emip->emi_poll_cnt++ == 0) { - if ((rc = siena_mcdi_poll_reboot(enp)) != 0) { - emip->emi_pending_req = NULL; - EFSYS_UNLOCK(enp->en_eslp, state); - - goto fail1; - } - } - - /* Check if a response is available */ - if (siena_mcdi_poll_response(enp) == B_FALSE) { - EFSYS_UNLOCK(enp->en_eslp, state); - return (B_FALSE); - } - - /* Read the response header */ - efx_mcdi_read_response_header(enp, emrp); - - /* Request complete */ - emip->emi_pending_req = NULL; - - EFSYS_UNLOCK(enp->en_eslp, state); - - if ((rc = emrp->emr_rc) != 0) - goto fail2; - - siena_mcdi_request_copyout(enp, emrp); - goto out; - -fail2: - if (!emrp->emr_quiet) - EFSYS_PROBE(fail2); -fail1: - if (!emrp->emr_quiet) - EFSYS_PROBE1(fail1, efx_rc_t, rc); - - /* Reboot/Assertion */ - if (rc == EIO || rc == EINTR) - efx_mcdi_raise_exception(enp, emrp, rc); - -out: - return (B_TRUE); -} - __checkReturn efx_rc_t siena_mcdi_init( __in efx_nic_t *enp, |