diff options
author | Jens Axboe <axboe@kernel.dk> | 2013-12-31 09:51:02 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-12-31 09:51:02 -0700 |
commit | b28bc9b38c52f63f43e3fd875af982f2240a2859 (patch) | |
tree | 76cdb7b52b58f5685993cc15ed81d1c903023358 /drivers/net/ethernet/sfc/mcdi.c | |
parent | 8d30726912cb39c3a3ebde06214d54861f8fdde2 (diff) | |
parent | 802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff) |
Merge tag 'v3.13-rc6' into for-3.14/core
Needed to bring blk-mq uptodate, since changes have been going in
since for-3.14/core was established.
Fixup merge issues related to the immutable biovec changes.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Conflicts:
block/blk-flush.c
fs/btrfs/check-integrity.c
fs/btrfs/extent_io.c
fs/btrfs/scrub.c
fs/logfs/dev_bdev.c
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi.c')
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 366c8e3e3784..4b0bd8a1514d 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -50,6 +50,7 @@ struct efx_mcdi_async_param { static void efx_mcdi_timeout_async(unsigned long context); static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, bool *was_attached_out); +static bool efx_mcdi_poll_once(struct efx_nic *efx); static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) { @@ -237,6 +238,21 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx) } } +static bool efx_mcdi_poll_once(struct efx_nic *efx) +{ + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); + + rmb(); + if (!efx->type->mcdi_poll_response(efx)) + return false; + + spin_lock_bh(&mcdi->iface_lock); + efx_mcdi_read_response_header(efx); + spin_unlock_bh(&mcdi->iface_lock); + + return true; +} + static int efx_mcdi_poll(struct efx_nic *efx) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); @@ -272,18 +288,13 @@ static int efx_mcdi_poll(struct efx_nic *efx) time = jiffies; - rmb(); - if (efx->type->mcdi_poll_response(efx)) + if (efx_mcdi_poll_once(efx)) break; if (time_after(time, finish)) return -ETIMEDOUT; } - spin_lock_bh(&mcdi->iface_lock); - efx_mcdi_read_response_header(efx); - spin_unlock_bh(&mcdi->iface_lock); - /* Return rc=0 like wait_event_timeout() */ return 0; } @@ -619,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, rc = efx_mcdi_await_completion(efx); if (rc != 0) { + netif_err(efx, hw, efx->net_dev, + "MC command 0x%x inlen %d mode %d timed out\n", + cmd, (int)inlen, mcdi->mode); + + if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) { + netif_err(efx, hw, efx->net_dev, + "MCDI request was completed without an event\n"); + rc = 0; + } + /* Close the race with efx_mcdi_ev_cpl() executing just too late * and completing a request we've just cancelled, by ensuring * that the seqno check therein fails. @@ -627,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, ++mcdi->seqno; ++mcdi->credits; spin_unlock_bh(&mcdi->iface_lock); + } - netif_err(efx, hw, efx->net_dev, - "MC command 0x%x inlen %d mode %d timed out\n", - cmd, (int)inlen, mcdi->mode); - } else { + if (rc == 0) { size_t hdr_len, data_len; /* At the very least we need a memory barrier here to ensure |