/*
* zfcp device driver
*
* Debug traces for zfcp.
*
* Copyright IBM Corporation 2002, 2009
*/
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/ctype.h>
#include <asm/debug.h>
#include "zfcp_dbf.h"
#include "zfcp_ext.h"
#include "zfcp_fc.h"
static u32 dbfsize = 4;
module_param(dbfsize, uint, 0400);
MODULE_PARM_DESC(dbfsize,
"number of pages for each debug feature area (default 4)");
static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
int level, char *from, int from_len)
{
int offset;
struct zfcp_dbf_dump *dump = to;
int room = to_len - sizeof(*dump);
for (offset = 0; offset < from_len; offset += dump->size) {
memset(to, 0, to_len);
strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
dump->total_size = from_len;
dump->offset = offset;
dump->size = min(from_len - offset, room);
memcpy(dump->data, from + offset, dump->size);
debug_event(dbf, level, dump, dump->size + sizeof(*dump));
}
}
static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
{
int i;
*p += sprintf(*p, "%-24s", label);
for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
*p += sprintf(*p, "%c", tag[i]);
*p += sprintf(*p, "\n");
}
static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
{
*buf += sprintf(*buf, "%-24s%s\n", s1, s2);
}
static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
{
va_list arg;
*buf += sprintf(*buf, "%-24s", s);
va_start(arg, format);
*buf += vsprintf(*buf, format, arg);
va_end(arg);
*buf += sprintf(*buf, "\n");
}
static void zfcp_dbf_outd(char **p, const char *label, char *buffer,
int buflen, int offset, int total_size)
{
if (!offset)
*p += sprintf(*p, "%-24s ", label);
while (buflen--) {
if (offset > 0) {
if ((offset % 32) == 0)
*p += sprintf(*p, "\n%-24c ", ' ');
else if ((offset % 4) == 0)
*p += sprintf(*p, " ");
}
*p += sprintf(*p, "%02x", *buffer++);
if (++offset == total_size) {
*p += sprintf(*p, "\n");
break;
}
}
if (!total_size)
*p += sprintf(*p, "\n");
}
static int zfcp_dbf_view_header(debug_info_t *id,