18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  QLogic FCoE Offload Driver
48c2ecf20Sopenharmony_ci *  Copyright (c) 2016-2018 Cavium Inc.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci#include "qedf_dbg.h"
78c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_civoid
108c2ecf20Sopenharmony_ciqedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
118c2ecf20Sopenharmony_ci	      const char *fmt, ...)
128c2ecf20Sopenharmony_ci{
138c2ecf20Sopenharmony_ci	va_list va;
148c2ecf20Sopenharmony_ci	struct va_format vaf;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	va_start(va, fmt);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	vaf.fmt = fmt;
198c2ecf20Sopenharmony_ci	vaf.va = &va;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	if (likely(qedf) && likely(qedf->pdev))
228c2ecf20Sopenharmony_ci		pr_err("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
238c2ecf20Sopenharmony_ci			func, line, qedf->host_no, &vaf);
248c2ecf20Sopenharmony_ci	else
258c2ecf20Sopenharmony_ci		pr_err("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	va_end(va);
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_civoid
318c2ecf20Sopenharmony_ciqedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
328c2ecf20Sopenharmony_ci	       const char *fmt, ...)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	va_list va;
358c2ecf20Sopenharmony_ci	struct va_format vaf;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	va_start(va, fmt);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	vaf.fmt = fmt;
408c2ecf20Sopenharmony_ci	vaf.va = &va;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	if (!(qedf_debug & QEDF_LOG_WARN))
438c2ecf20Sopenharmony_ci		goto ret;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	if (likely(qedf) && likely(qedf->pdev))
468c2ecf20Sopenharmony_ci		pr_warn("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
478c2ecf20Sopenharmony_ci			func, line, qedf->host_no, &vaf);
488c2ecf20Sopenharmony_ci	else
498c2ecf20Sopenharmony_ci		pr_warn("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciret:
528c2ecf20Sopenharmony_ci	va_end(va);
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_civoid
568c2ecf20Sopenharmony_ciqedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
578c2ecf20Sopenharmony_ci		 const char *fmt, ...)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	va_list va;
608c2ecf20Sopenharmony_ci	struct va_format vaf;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	va_start(va, fmt);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	vaf.fmt = fmt;
658c2ecf20Sopenharmony_ci	vaf.va = &va;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	if (!(qedf_debug & QEDF_LOG_NOTICE))
688c2ecf20Sopenharmony_ci		goto ret;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	if (likely(qedf) && likely(qedf->pdev))
718c2ecf20Sopenharmony_ci		pr_notice("[%s]:[%s:%d]:%d: %pV",
728c2ecf20Sopenharmony_ci			  dev_name(&(qedf->pdev->dev)), func, line,
738c2ecf20Sopenharmony_ci			  qedf->host_no, &vaf);
748c2ecf20Sopenharmony_ci	else
758c2ecf20Sopenharmony_ci		pr_notice("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ciret:
788c2ecf20Sopenharmony_ci	va_end(va);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_civoid
828c2ecf20Sopenharmony_ciqedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line,
838c2ecf20Sopenharmony_ci	       u32 level, const char *fmt, ...)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	va_list va;
868c2ecf20Sopenharmony_ci	struct va_format vaf;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	va_start(va, fmt);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	vaf.fmt = fmt;
918c2ecf20Sopenharmony_ci	vaf.va = &va;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if (!(qedf_debug & level))
948c2ecf20Sopenharmony_ci		goto ret;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	if (likely(qedf) && likely(qedf->pdev))
978c2ecf20Sopenharmony_ci		pr_info("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)),
988c2ecf20Sopenharmony_ci			func, line, qedf->host_no, &vaf);
998c2ecf20Sopenharmony_ci	else
1008c2ecf20Sopenharmony_ci		pr_info("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciret:
1038c2ecf20Sopenharmony_ci	va_end(va);
1048c2ecf20Sopenharmony_ci}
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciint
1078c2ecf20Sopenharmony_ciqedf_alloc_grc_dump_buf(u8 **buf, uint32_t len)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci		*buf = vmalloc(len);
1108c2ecf20Sopenharmony_ci		if (!(*buf))
1118c2ecf20Sopenharmony_ci			return -ENOMEM;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci		memset(*buf, 0, len);
1148c2ecf20Sopenharmony_ci		return 0;
1158c2ecf20Sopenharmony_ci}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_civoid
1188c2ecf20Sopenharmony_ciqedf_free_grc_dump_buf(uint8_t **buf)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci		vfree(*buf);
1218c2ecf20Sopenharmony_ci		*buf = NULL;
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ciint
1258c2ecf20Sopenharmony_ciqedf_get_grc_dump(struct qed_dev *cdev, const struct qed_common_ops *common,
1268c2ecf20Sopenharmony_ci		   u8 **buf, uint32_t *grcsize)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	if (!*buf)
1298c2ecf20Sopenharmony_ci		return -EINVAL;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	return common->dbg_all_data(cdev, *buf);
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_civoid
1358c2ecf20Sopenharmony_ciqedf_uevent_emit(struct Scsi_Host *shost, u32 code, char *msg)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	char event_string[40];
1388c2ecf20Sopenharmony_ci	char *envp[] = {event_string, NULL};
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	memset(event_string, 0, sizeof(event_string));
1418c2ecf20Sopenharmony_ci	switch (code) {
1428c2ecf20Sopenharmony_ci	case QEDF_UEVENT_CODE_GRCDUMP:
1438c2ecf20Sopenharmony_ci		if (msg)
1448c2ecf20Sopenharmony_ci			strscpy(event_string, msg, sizeof(event_string));
1458c2ecf20Sopenharmony_ci		else
1468c2ecf20Sopenharmony_ci			sprintf(event_string, "GRCDUMP=%u", shost->host_no);
1478c2ecf20Sopenharmony_ci		break;
1488c2ecf20Sopenharmony_ci	default:
1498c2ecf20Sopenharmony_ci		/* do nothing */
1508c2ecf20Sopenharmony_ci		break;
1518c2ecf20Sopenharmony_ci	}
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	kobject_uevent_env(&shost->shost_gendev.kobj, KOBJ_CHANGE, envp);
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ciint
1578c2ecf20Sopenharmony_ciqedf_create_sysfs_attr(struct Scsi_Host *shost, struct sysfs_bin_attrs *iter)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	int ret = 0;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	for (; iter->name; iter++) {
1628c2ecf20Sopenharmony_ci		ret = sysfs_create_bin_file(&shost->shost_gendev.kobj,
1638c2ecf20Sopenharmony_ci					    iter->attr);
1648c2ecf20Sopenharmony_ci		if (ret)
1658c2ecf20Sopenharmony_ci			pr_err("Unable to create sysfs %s attr, err(%d).\n",
1668c2ecf20Sopenharmony_ci			       iter->name, ret);
1678c2ecf20Sopenharmony_ci	}
1688c2ecf20Sopenharmony_ci	return ret;
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_civoid
1728c2ecf20Sopenharmony_ciqedf_remove_sysfs_attr(struct Scsi_Host *shost, struct sysfs_bin_attrs *iter)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	for (; iter->name; iter++)
1758c2ecf20Sopenharmony_ci		sysfs_remove_bin_file(&shost->shost_gendev.kobj, iter->attr);
1768c2ecf20Sopenharmony_ci}
177