debug.c 8.4 KB
Newer Older
A
Artem B. Bityutskiy 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright (c) International Business Machines Corp., 2006
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Author: Artem Bityutskiy (Битюцкий Артём)
 */

/*
 * Here we keep all the UBI debugging stuff which should normally be disabled
 * and compiled-out, but it is extremely helpful when hunting bugs or doing big
 * changes.
 */

27
#ifdef CONFIG_MTD_UBI_DEBUG
A
Artem B. Bityutskiy 已提交
28 29 30 31 32 33 34 35 36

#include "ubi.h"

/**
 * ubi_dbg_dump_ec_hdr - dump an erase counter header.
 * @ec_hdr: the erase counter header to dump
 */
void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
37 38 39 40 41 42 43 44 45 46
	printk(KERN_DEBUG "Erase counter header dump:\n");
	printk(KERN_DEBUG "\tmagic          %#08x\n",
	       be32_to_cpu(ec_hdr->magic));
	printk(KERN_DEBUG "\tversion        %d\n", (int)ec_hdr->version);
	printk(KERN_DEBUG "\tec             %llu\n",
	       (long long)be64_to_cpu(ec_hdr->ec));
	printk(KERN_DEBUG "\tvid_hdr_offset %d\n",
	       be32_to_cpu(ec_hdr->vid_hdr_offset));
	printk(KERN_DEBUG "\tdata_offset    %d\n",
	       be32_to_cpu(ec_hdr->data_offset));
47 48
	printk(KERN_DEBUG "\timage_seq      %d\n",
	       be32_to_cpu(ec_hdr->image_seq));
49 50 51
	printk(KERN_DEBUG "\thdr_crc        %#08x\n",
	       be32_to_cpu(ec_hdr->hdr_crc));
	printk(KERN_DEBUG "erase counter header hexdump:\n");
A
Artem Bityutskiy 已提交
52 53
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
		       ec_hdr, UBI_EC_HDR_SIZE, 1);
A
Artem B. Bityutskiy 已提交
54 55 56 57 58 59 60 61
}

/**
 * ubi_dbg_dump_vid_hdr - dump a volume identifier header.
 * @vid_hdr: the volume identifier header to dump
 */
void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
62 63 64 65 66 67 68 69 70 71 72 73
	printk(KERN_DEBUG "Volume identifier header dump:\n");
	printk(KERN_DEBUG "\tmagic     %08x\n", be32_to_cpu(vid_hdr->magic));
	printk(KERN_DEBUG "\tversion   %d\n",   (int)vid_hdr->version);
	printk(KERN_DEBUG "\tvol_type  %d\n",   (int)vid_hdr->vol_type);
	printk(KERN_DEBUG "\tcopy_flag %d\n",   (int)vid_hdr->copy_flag);
	printk(KERN_DEBUG "\tcompat    %d\n",   (int)vid_hdr->compat);
	printk(KERN_DEBUG "\tvol_id    %d\n",   be32_to_cpu(vid_hdr->vol_id));
	printk(KERN_DEBUG "\tlnum      %d\n",   be32_to_cpu(vid_hdr->lnum));
	printk(KERN_DEBUG "\tdata_size %d\n",   be32_to_cpu(vid_hdr->data_size));
	printk(KERN_DEBUG "\tused_ebs  %d\n",   be32_to_cpu(vid_hdr->used_ebs));
	printk(KERN_DEBUG "\tdata_pad  %d\n",   be32_to_cpu(vid_hdr->data_pad));
	printk(KERN_DEBUG "\tsqnum     %llu\n",
74
		(unsigned long long)be64_to_cpu(vid_hdr->sqnum));
75 76 77 78
	printk(KERN_DEBUG "\thdr_crc   %08x\n", be32_to_cpu(vid_hdr->hdr_crc));
	printk(KERN_DEBUG "Volume identifier header hexdump:\n");
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
		       vid_hdr, UBI_VID_HDR_SIZE, 1);
A
Artem B. Bityutskiy 已提交
79 80 81 82 83 84 85 86
}

/**
 * ubi_dbg_dump_vol_info- dump volume information.
 * @vol: UBI volume description object
 */
void ubi_dbg_dump_vol_info(const struct ubi_volume *vol)
{
87 88 89 90 91 92 93 94 95 96 97 98 99
	printk(KERN_DEBUG "Volume information dump:\n");
	printk(KERN_DEBUG "\tvol_id          %d\n", vol->vol_id);
	printk(KERN_DEBUG "\treserved_pebs   %d\n", vol->reserved_pebs);
	printk(KERN_DEBUG "\talignment       %d\n", vol->alignment);
	printk(KERN_DEBUG "\tdata_pad        %d\n", vol->data_pad);
	printk(KERN_DEBUG "\tvol_type        %d\n", vol->vol_type);
	printk(KERN_DEBUG "\tname_len        %d\n", vol->name_len);
	printk(KERN_DEBUG "\tusable_leb_size %d\n", vol->usable_leb_size);
	printk(KERN_DEBUG "\tused_ebs        %d\n", vol->used_ebs);
	printk(KERN_DEBUG "\tused_bytes      %lld\n", vol->used_bytes);
	printk(KERN_DEBUG "\tlast_eb_bytes   %d\n", vol->last_eb_bytes);
	printk(KERN_DEBUG "\tcorrupted       %d\n", vol->corrupted);
	printk(KERN_DEBUG "\tupd_marker      %d\n", vol->upd_marker);
A
Artem B. Bityutskiy 已提交
100 101 102

	if (vol->name_len <= UBI_VOL_NAME_MAX &&
	    strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
103
		printk(KERN_DEBUG "\tname            %s\n", vol->name);
A
Artem B. Bityutskiy 已提交
104
	} else {
105 106 107
		printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n",
		       vol->name[0], vol->name[1], vol->name[2],
		       vol->name[3], vol->name[4]);
A
Artem B. Bityutskiy 已提交
108 109 110 111 112 113 114 115 116 117
	}
}

/**
 * ubi_dbg_dump_vtbl_record - dump a &struct ubi_vtbl_record object.
 * @r: the object to dump
 * @idx: volume table index
 */
void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
118
	int name_len = be16_to_cpu(r->name_len);
A
Artem B. Bityutskiy 已提交
119

120 121 122 123 124 125 126 127
	printk(KERN_DEBUG "Volume table record %d dump:\n", idx);
	printk(KERN_DEBUG "\treserved_pebs   %d\n",
	       be32_to_cpu(r->reserved_pebs));
	printk(KERN_DEBUG "\talignment       %d\n", be32_to_cpu(r->alignment));
	printk(KERN_DEBUG "\tdata_pad        %d\n", be32_to_cpu(r->data_pad));
	printk(KERN_DEBUG "\tvol_type        %d\n", (int)r->vol_type);
	printk(KERN_DEBUG "\tupd_marker      %d\n", (int)r->upd_marker);
	printk(KERN_DEBUG "\tname_len        %d\n", name_len);
A
Artem B. Bityutskiy 已提交
128 129

	if (r->name[0] == '\0') {
130
		printk(KERN_DEBUG "\tname            NULL\n");
A
Artem B. Bityutskiy 已提交
131 132 133 134 135
		return;
	}

	if (name_len <= UBI_VOL_NAME_MAX &&
	    strnlen(&r->name[0], name_len + 1) == name_len) {
136
		printk(KERN_DEBUG "\tname            %s\n", &r->name[0]);
A
Artem B. Bityutskiy 已提交
137
	} else {
138
		printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n",
A
Artem B. Bityutskiy 已提交
139 140 141
			r->name[0], r->name[1], r->name[2], r->name[3],
			r->name[4]);
	}
142
	printk(KERN_DEBUG "\tcrc             %#08x\n", be32_to_cpu(r->crc));
A
Artem B. Bityutskiy 已提交
143 144 145 146 147 148 149 150
}

/**
 * ubi_dbg_dump_sv - dump a &struct ubi_scan_volume object.
 * @sv: the object to dump
 */
void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv)
{
151 152 153 154 155 156 157 158 159
	printk(KERN_DEBUG "Volume scanning information dump:\n");
	printk(KERN_DEBUG "\tvol_id         %d\n", sv->vol_id);
	printk(KERN_DEBUG "\thighest_lnum   %d\n", sv->highest_lnum);
	printk(KERN_DEBUG "\tleb_count      %d\n", sv->leb_count);
	printk(KERN_DEBUG "\tcompat         %d\n", sv->compat);
	printk(KERN_DEBUG "\tvol_type       %d\n", sv->vol_type);
	printk(KERN_DEBUG "\tused_ebs       %d\n", sv->used_ebs);
	printk(KERN_DEBUG "\tlast_data_size %d\n", sv->last_data_size);
	printk(KERN_DEBUG "\tdata_pad       %d\n", sv->data_pad);
A
Artem B. Bityutskiy 已提交
160 161 162 163 164 165 166 167 168
}

/**
 * ubi_dbg_dump_seb - dump a &struct ubi_scan_leb object.
 * @seb: the object to dump
 * @type: object type: 0 - not corrupted, 1 - corrupted
 */
void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type)
{
169 170 171
	printk(KERN_DEBUG "eraseblock scanning information dump:\n");
	printk(KERN_DEBUG "\tec       %d\n", seb->ec);
	printk(KERN_DEBUG "\tpnum     %d\n", seb->pnum);
A
Artem B. Bityutskiy 已提交
172
	if (type == 0) {
173 174 175
		printk(KERN_DEBUG "\tlnum     %d\n", seb->lnum);
		printk(KERN_DEBUG "\tscrub    %d\n", seb->scrub);
		printk(KERN_DEBUG "\tsqnum    %llu\n", seb->sqnum);
A
Artem B. Bityutskiy 已提交
176 177 178 179 180 181 182 183 184 185 186
	}
}

/**
 * ubi_dbg_dump_mkvol_req - dump a &struct ubi_mkvol_req object.
 * @req: the object to dump
 */
void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
{
	char nm[17];

187 188 189 190 191 192
	printk(KERN_DEBUG "Volume creation request dump:\n");
	printk(KERN_DEBUG "\tvol_id    %d\n",   req->vol_id);
	printk(KERN_DEBUG "\talignment %d\n",   req->alignment);
	printk(KERN_DEBUG "\tbytes     %lld\n", (long long)req->bytes);
	printk(KERN_DEBUG "\tvol_type  %d\n",   req->vol_type);
	printk(KERN_DEBUG "\tname_len  %d\n",   req->name_len);
A
Artem B. Bityutskiy 已提交
193 194 195

	memcpy(nm, req->name, 16);
	nm[16] = 0;
196
	printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
A
Artem B. Bityutskiy 已提交
197 198
}

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
/**
 * ubi_dbg_dump_flash - dump a region of flash.
 * @ubi: UBI device description object
 * @pnum: the physical eraseblock number to dump
 * @offset: the starting offset within the physical eraseblock to dump
 * @len: the length of the region to dump
 */
void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
{
	int err;
	size_t read;
	void *buf;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;

	buf = vmalloc(len);
	if (!buf)
		return;
	err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
	if (err && err != -EUCLEAN) {
		ubi_err("error %d while reading %d bytes from PEB %d:%d, "
			"read %zd bytes", err, len, pnum, offset, read);
		goto out;
	}

	dbg_msg("dumping %d bytes of data from PEB %d, offset %d",
		len, pnum, offset);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
out:
	vfree(buf);
	return;
}

231
#endif /* CONFIG_MTD_UBI_DEBUG */