aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/android
ModeNameSize
-rw-r--r--Kconfig825logplain
-rw-r--r--Makefile178logplain
-rw-r--r--TODO923logplain
-rw-r--r--ashmem.c23979logplain
-rw-r--r--ashmem.h545logplain
d---------ion305logplain
d---------uapi107logplain
-rw-r--r--vsoc.c33120logplain
r on MLX4_CMD_HW2SW_MPT is fatal except when fw status equals * CMD_STAT_REG_BOUND. * This status indicates that memory region has memory windows bound to it * which may result from invalid user space usage and is not fatal. */ if (op == MLX4_CMD_HW2SW_MPT && fw_status != CMD_STAT_REG_BOUND) return 1; return 0; } static int mlx4_cmd_reset_flow(struct mlx4_dev *dev, u16 op, u8 op_modifier, int err) { /* Only if reset flow is really active return code is based on * command, otherwise current error code is returned. */ if (mlx4_internal_err_reset) { mlx4_enter_error_state(dev->persist); err = mlx4_internal_err_ret_value(dev, op, op_modifier); } return err; } static int comm_pending(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); u32 status = readl(&priv->mfunc.comm->slave_read); return (swab32(status) >> 31) != priv->cmd.comm_toggle; } static int mlx4_comm_cmd_post(struct mlx4_dev *dev, u8 cmd, u16 param) { struct mlx4_priv *priv = mlx4_priv(dev); u32 val; /* To avoid writing to unknown addresses after the device state was * changed to internal error and the function was rest, * check the INTERNAL_ERROR flag which is updated under * device_state_mutex lock. */ mutex_lock(&dev->persist->device_state_mutex); if (dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR) { mutex_unlock(&dev->persist->device_state_mutex); return -EIO; } priv->cmd.comm_toggle ^= 1; val = param | (cmd << 16) | (priv->cmd.comm_toggle << 31); __raw_writel((__force u32) cpu_to_be32(val), &priv->mfunc.comm->slave_write); mmiowb(); mutex_unlock(&dev->persist->device_state_mutex); return 0; } static int mlx4_comm_cmd_poll(struct mlx4_dev *dev, u8 cmd, u16 param, unsigned long timeout) { struct mlx4_priv *priv = mlx4_priv(dev); unsigned long end; int err = 0; int ret_from_pending = 0; /* First, verify that the master reports correct status */ if (comm_pending(dev)) { mlx4_warn(dev, "Communication channel is not idle - my toggle is %d (cmd:0x%x)\n", priv->cmd.comm_toggle, cmd); return -EAGAIN; } /* Write command */ down(&priv->cmd.poll_sem); if (mlx4_comm_cmd_post(dev, cmd, param)) { /* Only in case the device state is INTERNAL_ERROR, * mlx4_comm_cmd_post returns with an error */ err = mlx4_status_to_errno(CMD_STAT_INTERNAL_ERR); goto out; } end = msecs_to_jiffies(timeout) + jiffies; while (comm_pending(dev) && time_before(jiffies, end)) cond_resched(); ret_from_pending = comm_pending(dev); if (ret_from_pending) { /* check if the slave is trying to boot in the middle of * FLR process. The only non-zero result in the RESET command * is MLX4_DELAY_RESET_SLAVE*/ if ((MLX4_COMM_CMD_RESET == cmd)) { err = MLX4_DELAY_RESET_SLAVE; goto out; } else { mlx4_warn(dev, "Communication channel command 0x%x timed out\n", cmd); err = mlx4_status_to_errno(CMD_STAT_INTERNAL_ERR); } } if (err) mlx4_enter_error_state(dev->persist); out: up(&priv->cmd.poll_sem); return err; } static int mlx4_comm_cmd_wait(struct mlx4_dev *dev, u8 vhcr_cmd, u16 param, u16 op, unsigned long timeout) { struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd; struct mlx4_cmd_context *context; unsigned long end; int err = 0; down(&cmd->event_sem); spin_lock(&cmd->context_lock); BUG_ON(cmd->free_head < 0); context = &cmd->context[cmd->free_head]; context->token += cmd->token_mask + 1; cmd->free_head = context->next; spin_unlock(&cmd->context_lock); reinit_completion(&context->done); if (mlx4_comm_cmd_post(dev, vhcr_cmd, param)) { /* Only in case the device state is INTERNAL_ERROR, * mlx4_comm_cmd_post returns with an error */ err = mlx4_status_to_errno(CMD_STAT_INTERNAL_ERR); goto out; } if (!wait_for_completion_timeout(&context->done, msecs_to_jiffies(timeout))) { mlx4_warn(dev, "communication channel command 0x%x (op=0x%x) timed out\n", vhcr_cmd, op); goto out_reset; } err = context->result; if (err && context->fw_status != CMD_STAT_MULTI_FUNC_REQ) { mlx4_err(dev, "command 0x%x failed: fw status = 0x%x\n", vhcr_cmd, context->fw_status); if (mlx4_closing_cmd_fatal_error(op, context->fw_status)) goto out_reset; } /* wait for comm channel ready * this is necessary for prevention the race * when switching between event to polling mode * Skipping this section in case the device is in FATAL_ERROR state, * In this state, no commands are sent via the comm channel until * the device has returned from reset. */ if (!(dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)) { end = msecs_to_jiffies(timeout) + jiffies; while (comm_pending(dev) && time_before(jiffies, end)) cond_resched(); } goto out; out_reset: err = mlx4_status_to_errno(CMD_STAT_INTERNAL_ERR); mlx4_enter_error_state(dev->persist); out: spin_lock(&cmd->context_lock); context->next = cmd->free_head; cmd->free_head = context - cmd->context; spin_unlock(&cmd->context_lock); up(&cmd->ev