FreeBSD/sys/dev/mlx5/mlx5_core/mlx5_cmd.c
/*  Notes:
 *    1. Callback functions may not sleep
 *    2. page queue commands do not support asynchrous completion
 */
1. Callback functions may not sleep
2. page queue commands do not support asynchrous completion
1 . Callback functions may not sleep 2 . page queue commands do not support asynchrous completion
static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
			   struct mlx5_cmd_msg *out, void *uout, int uout_size,
			   mlx5_cmd_cbk_t callback,
			   void *context, int page_queue, u8 *status)
{
	struct mlx5_cmd *cmd = &dev->cmd;
	struct mlx5_cmd_work_ent *ent;
	struct mlx5_cmd_stats *stats;
	int err = 0;
	s64 ds;
	u16 op;
	if (callback && page_queue)
		return -EINVAL;
	ent = alloc_cmd(cmd, in, out, uout, uout_size, callback, context,
			page_queue);
	if (IS_ERR(ent))
		return PTR_ERR(ent);
	if (!callback)
		init_completion(&ent->done);
	INIT_WORK(&ent->work, cmd_work_handler);
	if (page_queue) {
		cmd_work_handler(&ent->work);
	} else if (!queue_work(cmd->wq, &ent->work)) {
		mlx5_core_warn(dev, "failed to queue work\n");
		err = -ENOMEM;
		goto out_free;
	}
	if (!callback) {
		err = wait_func(dev, ent);
		if (err == -ETIMEDOUT)
			goto out;
		ds = ent->ts2 - ent->ts1;
		op = be16_to_cpu(((struct mlx5_inbox_hdr *)in->first.data)->opcode);
		if (op < ARRAY_SIZE(cmd->stats)) {
			stats = &cmd->stats[op];
			spin_lock_irq(&stats->lock);
			stats->sum += ds;
			++stats->n;
			spin_unlock_irq(&stats->lock);
		}
		mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
				   "fw exec time for %s is %lld nsec\n",
				   mlx5_command_str(op), (long long)ds);
		*status = ent->status;
		free_cmd(ent);
	}
	return err;
out_free:
	free_cmd(ent);
out:
	return err;
}
static int mlx5_cmd_invoke ( struct mlx5_core_dev * dev , struct mlx5_cmd_msg * in , struct mlx5_cmd_msg * out , void * uout , int uout_size , mlx5_cmd_cbk_t callback , void * context , int page_queue , u8 * status ) { struct mlx5_cmd * cmd = & dev -> cmd ; struct mlx5_cmd_work_ent * ent ; struct mlx5_cmd_stats * stats ; int err = 0 ; s64 ds ; u16 op ; if ( callback && page_queue ) return - EINVAL ; ent = alloc_cmd ( cmd , in , out , uout , uout_size , callback , context , page_queue ) ; if ( IS_ERR ( ent ) ) return PTR_ERR ( ent ) ; if ( ! callback ) init_completion ( & ent -> done ) ; INIT_WORK ( & ent -> work , cmd_work_handler ) ; if ( page_queue ) { cmd_work_handler ( & ent -> work ) ; } else if ( ! queue_work ( cmd -> wq , & ent -> work ) ) { mlx5_core_warn ( dev , " \n " ) ; err = - ENOMEM ; goto out_free ; } if ( ! callback ) { err = wait_func ( dev , ent ) ; if ( err == - ETIMEDOUT ) goto out ; ds = ent -> ts2 - ent -> ts1 ; op = be16_to_cpu ( ( ( struct mlx5_inbox_hdr * ) in -> first . data ) -> opcode ) ; if ( op < ARRAY_SIZE ( cmd -> stats ) ) { stats = & cmd -> stats [ op ] ; spin_lock_irq ( & stats -> lock ) ; stats -> sum += ds ; ++ stats -> n ; spin_unlock_irq ( & stats -> lock ) ; } mlx5_core_dbg_mask ( dev , 1 << MLX5_CMD_TIME , " \n " , mlx5_command_str ( op ) , ( long long ) ds ) ; * status = ent -> status ; free_cmd ( ent ) ; } return err ; out_free : free_cmd ( ent ) ; out : return err ; }
Notes:
    1.
Notes : 1 .