203 mutex_unlock(&cmd->hcr_mutex);
204 return ret;
205}
206
207static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
208 int out_is_imm, u32 in_modifier, u8 op_modifier,
209 u16 op, unsigned long timeout)
210{
211 struct mlx4_priv *priv = mlx4_priv(dev);
212 void __iomem *hcr = priv->cmd.hcr;
213 int err = 0;
214 unsigned long end;
215
216 down(&priv->cmd.poll_sem);
217
218 err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0,
219 in_modifier, op_modifier, op, CMD_POLL_TOKEN, 0);
220 if (err)
221 goto out;
222
223 end = msecs_to_jiffies(timeout) + jiffies;
224 while (cmd_pending(dev) && time_before(jiffies, end))
225 cond_resched();
226
227 if (cmd_pending(dev)) {
228 err = -ETIMEDOUT;
229 goto out;
230 }
231
232 if (out_is_imm)
233 *out_param =
234 (u64) be32_to_cpu((__force __be32)
235 __raw_readl(hcr + HCR_OUT_PARAM_OFFSET)) << 32 |
236 (u64) be32_to_cpu((__force __be32)
237 __raw_readl(hcr + HCR_OUT_PARAM_OFFSET + 4));
238
239 err = mlx4_status_to_errno(be32_to_cpu((__force __be32)
240 __raw_readl(hcr + HCR_STATUS_OFFSET)) >> 24);
241
242out:
243 up(&priv->cmd.poll_sem);