10cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger/*
20cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * Copyright (c) 2012 Mike Frysinger <vapier@gentoo.org>
30cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *
40cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * Redistribution and use in source and binary forms, with or without
50cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * modification, are permitted provided that the following conditions
60cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * are met:
70cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * 1. Redistributions of source code must retain the above copyright
80cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *    notice, this list of conditions and the following disclaimer.
90cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * 2. Redistributions in binary form must reproduce the above copyright
100cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *    notice, this list of conditions and the following disclaimer in the
110cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *    documentation and/or other materials provided with the distribution.
120cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * 3. The name of the author may not be used to endorse or promote products
130cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *    derived from this software without specific prior written permission.
140cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger *
150cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
160cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
170cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
180cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
190cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
200cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
210cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
220cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
240cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger */
260cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
270cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger#include "defs.h"
280cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
29a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin#include DEF_MPERS_TYPE(struct_mtd_oob_buf)
30a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin
31eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin#include <linux/ioctl.h>
320cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
330cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger/* The mtd api changes quickly, so we have to keep a local copy */
340cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger#include <linux/version.h>
350cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
360cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger# include "mtd-abi.h"
370cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger#else
380cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger# include <mtd/mtd-abi.h>
390cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger#endif
400cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
41a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levintypedef struct mtd_oob_buf struct_mtd_oob_buf;
42a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin
43a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin#include MPERS_DEFS
44a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin
450ed617bd66624cec6138102545d73b2e2346f1f6Dmitry V. Levin#include "xlat/mtd_mode_options.h"
46eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin#include "xlat/mtd_file_mode_options.h"
470ed617bd66624cec6138102545d73b2e2346f1f6Dmitry V. Levin#include "xlat/mtd_type_options.h"
480ed617bd66624cec6138102545d73b2e2346f1f6Dmitry V. Levin#include "xlat/mtd_flags_options.h"
490ed617bd66624cec6138102545d73b2e2346f1f6Dmitry V. Levin#include "xlat/mtd_otp_options.h"
500ed617bd66624cec6138102545d73b2e2346f1f6Dmitry V. Levin#include "xlat/mtd_nandecc_options.h"
510cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
520a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
53d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_erase_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
540cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger{
550a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct erase_info_user einfo;
560cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
570a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
580a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &einfo))
590a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
60eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
610a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{start=%#x, length=%#x}", einfo.start, einfo.length);
620a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
630cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
640a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
65d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_erase_info_user64(struct tcb *const tcp, const kernel_ulong_t addr)
660a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
670a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct erase_info_user64 einfo64;
680cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
690a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
700a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &einfo64))
710a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
720cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
730a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{start=%#" PRIx64 ", length=%#" PRIx64 "}",
740a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) einfo64.start, (uint64_t) einfo64.length);
750a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
76eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
770a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
78d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_mtd_oob_buf(struct tcb *const tcp, const kernel_ulong_t addr)
790a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
80a0866bce3560aefe25a51bcdb659108172d5f926Dmitry V. Levin	struct_mtd_oob_buf mbuf;
810cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
820a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
830a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &mbuf))
840a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
85eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
86484326dbd8f8e02983e37498b4b5fa990d16b536Dmitry V. Levin	tprintf("{start=%#x, length=%#x, ptr=", mbuf.start, mbuf.length);
87d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	printaddr(ptr_to_kulong(mbuf.ptr));
88484326dbd8f8e02983e37498b4b5fa990d16b536Dmitry V. Levin	tprints("}");
890a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
900cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
910a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
92d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_mtd_oob_buf64(struct tcb *const tcp, const kernel_ulong_t addr)
930a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
940a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct mtd_oob_buf64 mbuf64;
950cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
960a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
970a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &mbuf64))
980a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
990cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
1000a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{start=%#" PRIx64 ", length=%#x, usr_ptr=%#" PRIx64 "}",
1010a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) mbuf64.start, mbuf64.length,
1020a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) mbuf64.usr_ptr);
1030a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
104eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
1050a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
106d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_otp_info(struct tcb *const tcp, const kernel_ulong_t addr)
1070a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
1080a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct otp_info oinfo;
1090a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1100a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
1110a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &oinfo))
1120a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
1130a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1140a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{start=%#x, length=%#x, locked=%u}",
1150a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		oinfo.start, oinfo.length, oinfo.locked);
1160a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
1170a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1180a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
119d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_otp_select(struct tcb *const tcp, const kernel_ulong_t addr)
1200a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
1210a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	unsigned int i;
1220a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1230a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
1240a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &i))
1250a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
1260a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1270a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("[");
1280a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	printxval(mtd_otp_options, i, "MTD_OTP_???");
1290a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("]");
1300a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
1310a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1320a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
133d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_mtd_write_req(struct tcb *const tcp, const kernel_ulong_t addr)
1340a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
1350a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct mtd_write_req mreq;
1360a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1370a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
1380a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &mreq))
1390a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
1400a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1410a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{start=%#" PRIx64 ", len=%#" PRIx64
1420a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		", ooblen=%#" PRIx64 ", usr_data=%#" PRIx64
1430a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		", usr_oob=%#" PRIx64 ", mode=",
1440a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) mreq.start, (uint64_t) mreq.len,
1450a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) mreq.ooblen, (uint64_t) mreq.usr_data,
1460a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) mreq.usr_oob);
1470a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	printxval(mtd_mode_options, mreq.mode, "MTD_OPS_???");
1480a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("}");
1490a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
1500a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1510a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
152d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_mtd_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
1530a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
1540a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct mtd_info_user minfo;
1550a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1560a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
1570a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &minfo))
1580a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
1590a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1600a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("{type=");
1610a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	printxval(mtd_type_options, minfo.type, "MTD_???");
1620a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", flags=");
1630a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	printflags(mtd_flags_options, minfo.flags, "MTD_???");
1640a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf(", size=%#x, erasesize=%#x, writesize=%#x, oobsize=%#x"
1650a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		", padding=%#" PRIx64 "}",
1660a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		minfo.size, minfo.erasesize, minfo.writesize, minfo.oobsize,
1670a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		(uint64_t) minfo.padding);
1680a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
1690a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1700a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
171d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_nand_oobinfo(struct tcb *const tcp, const kernel_ulong_t addr)
1720a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
1730a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct nand_oobinfo ninfo;
1740a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	unsigned int i, j;
1750a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1760a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
1770a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &ninfo))
1780a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
1790a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1800a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("{useecc=");
1810a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	printxval(mtd_nandecc_options, ninfo.useecc, "MTD_NANDECC_???");
1820a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf(", eccbytes=%#x", ninfo.eccbytes);
1830a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
1840a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", oobfree={");
1850a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	for (i = 0; i < ARRAY_SIZE(ninfo.oobfree); ++i) {
1860a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (i)
1870a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprints("}, ");
1880a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		tprints("{");
1890a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		for (j = 0; j < ARRAY_SIZE(ninfo.oobfree[0]); ++j) {
1900a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			if (j)
1910a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin				tprints(", ");
1920a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprintf("%#x", ninfo.oobfree[i][j]);
1930a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		}
194eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	}
195eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
1960a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("}}, eccpos={");
1970a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	for (i = 0; i < ARRAY_SIZE(ninfo.eccpos); ++i) {
1980a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (i)
1990a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprints(", ");
2000a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		tprintf("%#x", ninfo.eccpos[i]);
2010a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	}
202eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2030a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("}");
2040a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
2050a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
2060a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
207d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_nand_ecclayout_user(struct tcb *const tcp, const kernel_ulong_t addr)
2080a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
2090a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct nand_ecclayout_user nlay;
2100a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	unsigned int i;
2110a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
2120a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
2130a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &nlay))
2140a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
2150a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
2160a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{eccbytes=%#x, eccpos={", nlay.eccbytes);
2170a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	for (i = 0; i < ARRAY_SIZE(nlay.eccpos); ++i) {
2180a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (i)
219eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin			tprints(", ");
2200a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		tprintf("%#x", nlay.eccpos[i]);
221eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	}
2220a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("}, oobavail=%#x, oobfree={", nlay.oobavail);
2230a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	for (i = 0; i < ARRAY_SIZE(nlay.oobfree); ++i) {
2240a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (i)
2250a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprints(", ");
2260a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		tprintf("{offset=%#x, length=%#x}",
2270a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			nlay.oobfree[i].offset, nlay.oobfree[i].length);
2280a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	}
2290a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints("}");
2300a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
231eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2320a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levinstatic void
233d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesdecode_mtd_ecc_stats(struct tcb *const tcp, const kernel_ulong_t addr)
2340a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
2350a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	struct mtd_ecc_stats es;
236eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2370a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprints(", ");
2380a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	if (umove_or_printaddr(tcp, addr, &es))
2390a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		return;
240eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2410a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	tprintf("{corrected=%#x, failed=%#x, badblocks=%#x, bbtblocks=%#x}",
2420a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		es.corrected, es.failed, es.badblocks, es.bbtblocks);
2430a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin}
2440a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
245d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott HughesMPERS_PRINTER_DECL(int, mtd_ioctl, struct tcb *const tcp,
246d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes		   const unsigned int code, const kernel_ulong_t arg)
2470a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin{
2480a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	switch (code) {
2490a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMERASE:
2500a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMLOCK:
2510a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMUNLOCK:
2520a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMISLOCKED:
2530a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_erase_info_user(tcp, arg);
254eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
255eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2560a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMERASE64:
2570a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_erase_info_user64(tcp, arg);
2580a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		break;
2590cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
2600a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMWRITEOOB:
2610a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMREADOOB:
2620a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_mtd_oob_buf(tcp, arg);
2630a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		break;
264eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2650a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMWRITEOOB64:
2660a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMREADOOB64:
2670a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_mtd_oob_buf64(tcp, arg);
268eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
269eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2700a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMWRITE:
2710a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_mtd_write_req(tcp, arg);
2720a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		break;
273eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2740a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case OTPGETREGIONINFO:
2750a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (entering(tcp))
2760a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			return 0;
2770a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		/* fall through */
2780a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case OTPLOCK:
2790a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_otp_info(tcp, arg);
2800a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		break;
281eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2820a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case OTPSELECT:
2830a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_otp_select(tcp, arg);
284eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
285eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
286eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	case MTDFILEMODE:
287eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		tprints(", ");
288d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes		printxval64(mtd_file_mode_options, arg, "MTD_FILE_MODE_???");
289eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
290eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
291eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	case MEMGETBADBLOCK:
292eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	case MEMSETBADBLOCK:
293eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		tprints(", ");
294dd5f0cef93db377bc7bc0f4abc7c1003d67c2c95Dmitry V. Levin		printnum_int64(tcp, arg, "%" PRIu64);
295eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
296eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
2970a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMGETINFO:
298eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
2990cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
3000a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_mtd_info_user(tcp, arg);
301eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
3020cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
3030a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMGETOOBSEL:
304eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
3050cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
3060a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_nand_oobinfo(tcp, arg);
307eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
308eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
3090a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case ECCGETLAYOUT:
310eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
3110cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
3120a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_nand_ecclayout_user(tcp, arg);
313eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
3140cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
3150a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case ECCGETSTATS:
316eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
3170cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
3180a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		decode_mtd_ecc_stats(tcp, arg);
319eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
3200cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
321eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	case OTPGETREGIONCOUNT:
322eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
3230cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
3240cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger		tprints(", ");
325eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		printnum_int(tcp, arg, "%u");
326eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
3270cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
328eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	case MEMGETREGIONCOUNT:
329eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		if (entering(tcp))
3300cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger			return 0;
331eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		tprints(", ");
332eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		printnum_int(tcp, arg, "%d");
333eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		break;
3340cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger
3350a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin	case MEMGETREGIONINFO:
3360a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		if (entering(tcp)) {
3370a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			struct region_info_user rinfo;
3380a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
3390a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprints(", ");
3400a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			if (umove_or_printaddr(tcp, arg, &rinfo))
3410a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin				break;
3420a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprintf("{regionindex=%#x", rinfo.regionindex);
3430a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			return 0;
3440a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		} else {
3450a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			struct region_info_user rinfo;
3460a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
3470a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			if (!syserror(tcp) && !umove(tcp, arg, &rinfo))
3480a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin				tprintf(", offset=%#x"
3490a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin					", erasesize=%#x"
3500a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin					", numblocks=%#x}",
3510a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin					rinfo.offset,
3520a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin					rinfo.erasesize,
3530a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin					rinfo.numblocks);
3540a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			tprints("}");
3550a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin			break;
3560a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin		}
3570a27c814b2d62cc8319bff729f8ae18cdaed9bb4Dmitry V. Levin
3580cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger	default:
359eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin		return RVAL_DECODED;
3600cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger	}
361eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin
362eddefd64c3ad70bd4dbec22838cdd45f87c14cffDmitry V. Levin	return RVAL_DECODED | 1;
3630cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger}
364