// SPDX-License-Identifier: GPL-2.0-only
/*
 *  QLogic FCoE Offload Driver
 *  Copyright (c) 2016-2018 Cavium Inc.
 */
#include "qedf_dbg.h"
#include <linux/vmalloc.h>

void
qedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
	      const char *fmt, ...)
{
	va_list va;
	struct va_format vaf;

	va_start(va, fmt);

	vaf.fmt = fmt;
	vaf.va = &va;

	if (likely(qedf) && likely(qedf->pdev))
		pr_err("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
			func, line, qedf->host_no, &vaf);
	else
		pr_err("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);

	va_end(va);
}

void
qedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
	       const char *fmt, ...)
{
	va_list va;
	struct va_format vaf;

	va_start(va, fmt);

	vaf.fmt = fmt;
	vaf.va = &va;

	if (!(qedf_debug & QEDF_LOG_WARN))
		goto ret;

	if (likely(qedf) && likely(qedf->pdev))
		pr_warn("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
			func, line, qedf->host_no, &vaf);
	else
		pr_warn("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);

ret:
	va_end(va);
}

void
qedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
		 const char *fmt, ...)
{
	va_list va;
	struct va_format vaf;

	va_start(va, fmt);

	vaf.fmt = fmt;
	vaf.va = &va;

	if (!(qedf_debug & QEDF_LOG_NOTICE))
		goto ret;

	if (likely(qedf) && likely(qedf->pdev))
		pr_notice("[%s]:[%s:%d]:%d: %pV",
			  dev_name(&(qedf->pdev->dev)), func, line,
			  qedf->host_no, &vaf);
	else
		pr_notice("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);

ret:
	va_end(va);
}

void
qedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
	       u32 level, const char *fmt, ...)
{
	va_list va;
	struct va_format vaf;

	va_start(va, fmt);

	vaf.fmt = fmt;
	vaf.va = &va;

	if (!(qedf_debug & level))
		goto ret;

	if (likely(qedf) && likely(qedf->pdev))
		pr_info("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
			func, line, qedf->host_no, &vaf);
	else
		pr_info("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);

ret:
	va_end(va);
}

int
qedf_alloc_grc_dump_buf(u8 **buf, uint32_t len)
{
		*buf = vzalloc(len);
		if (!(*buf))
			return -ENOMEM;

		return 0;
}

void
qedf_free_grc_dump_buf(uint8_t **buf)
{
		vfree(*buf);
		*buf = NULL;
}

int
qedf_get_grc_dump(struct qed_dev *cdev, const struct qed_common_ops *common,
		   u8 **buf, uint32_t *grcsize)
{
	if (!*buf)
		return -EINVAL;

	return common->dbg_all_data(cdev, *buf);
}

void
qedf_uevent_emit(struct Scsi_Host *shost, u32 code, char *msg)
{
	char event_string[40];
	char *envp[] = {event_string, NULL};

	memset(event_string, 0, sizeof(event_string));
	switch (code) {
	case QEDF_UEVENT_CODE_GRCDUMP:
		if (msg)
			strscpy(event_string, msg, sizeof(event_string));
		else
			sprintf(event_string, "GRCDUMP=%u", shost->host_no);
		break;
	default:
		/* do nothing */
		break;
	}

	kobject_uevent_env(&shost->shost_gendev.kobj, KOBJ_CHANGE, envp);
}

int
qedf_create_sysfs_attr(struct Scsi_Host *shost, struct sysfs_bin_attrs *iter)
{
	int ret = 0;

	for (; iter->name; iter++) {
		ret = sysfs_create_bin_file(&shost->shost_gendev.kobj,
					    iter->attr);
		if (ret)
			pr_err("Unable to create sysfs %s attr, err(%d).\n",
			       iter->name, ret);
	}
	return ret;
}

void
qedf_remove_sysfs_attr(struct Scsi_Host *shost, struct sysfs_bin_attrs *iter)
{
	for (; iter->name; iter++)
		sysfs_remove_bin_file(&shost->shost_gendev.kobj, iter->attr);
}
