2 * Copyright (c) 2012 Mike Frysinger <vapier@gentoo.org>
3 * Copyright (c) 2012-2018 The strace developers.
5 * SPDX-License-Identifier: LGPL-2.1-or-later
10 #ifdef HAVE_STRUCT_MTD_WRITE_REQ
12 # include DEF_MPERS_TYPE(struct_mtd_oob_buf)
14 # include <linux/ioctl.h>
15 # include <mtd/mtd-abi.h>
17 typedef struct mtd_oob_buf struct_mtd_oob_buf;
19 #endif /* HAVE_STRUCT_MTD_WRITE_REQ */
23 #ifdef HAVE_STRUCT_MTD_WRITE_REQ
25 # include "xlat/mtd_mode_options.h"
26 # include "xlat/mtd_file_mode_options.h"
27 # include "xlat/mtd_type_options.h"
28 # include "xlat/mtd_flags_options.h"
29 # include "xlat/mtd_otp_options.h"
30 # include "xlat/mtd_nandecc_options.h"
33 decode_erase_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
35 struct erase_info_user einfo;
38 if (umove_or_printaddr(tcp, addr, &einfo))
41 tprintf("{start=%#x, length=%#x}", einfo.start, einfo.length);
45 decode_erase_info_user64(struct tcb *const tcp, const kernel_ulong_t addr)
47 struct erase_info_user64 einfo64;
50 if (umove_or_printaddr(tcp, addr, &einfo64))
53 tprintf("{start=%#" PRIx64 ", length=%#" PRIx64 "}",
54 (uint64_t) einfo64.start, (uint64_t) einfo64.length);
58 decode_mtd_oob_buf(struct tcb *const tcp, const kernel_ulong_t addr)
60 struct_mtd_oob_buf mbuf;
63 if (umove_or_printaddr(tcp, addr, &mbuf))
66 tprintf("{start=%#x, length=%#x, ptr=", mbuf.start, mbuf.length);
67 printaddr(ptr_to_kulong(mbuf.ptr));
72 decode_mtd_oob_buf64(struct tcb *const tcp, const kernel_ulong_t addr)
74 struct mtd_oob_buf64 mbuf64;
77 if (umove_or_printaddr(tcp, addr, &mbuf64))
80 tprintf("{start=%#" PRIx64 ", length=%#x, usr_ptr=%#" PRIx64 "}",
81 (uint64_t) mbuf64.start, mbuf64.length,
82 (uint64_t) mbuf64.usr_ptr);
86 decode_otp_info(struct tcb *const tcp, const kernel_ulong_t addr)
88 struct otp_info oinfo;
91 if (umove_or_printaddr(tcp, addr, &oinfo))
94 tprintf("{start=%#x, length=%#x, locked=%u}",
95 oinfo.start, oinfo.length, oinfo.locked);
99 decode_otp_select(struct tcb *const tcp, const kernel_ulong_t addr)
104 if (umove_or_printaddr(tcp, addr, &i))
108 printxval(mtd_otp_options, i, "MTD_OTP_???");
113 decode_mtd_write_req(struct tcb *const tcp, const kernel_ulong_t addr)
115 struct mtd_write_req mreq;
118 if (umove_or_printaddr(tcp, addr, &mreq))
121 tprintf("{start=%#" PRIx64 ", len=%#" PRIx64
122 ", ooblen=%#" PRIx64 ", usr_data=%#" PRIx64
123 ", usr_oob=%#" PRIx64 ", mode=",
124 (uint64_t) mreq.start, (uint64_t) mreq.len,
125 (uint64_t) mreq.ooblen, (uint64_t) mreq.usr_data,
126 (uint64_t) mreq.usr_oob);
127 printxval(mtd_mode_options, mreq.mode, "MTD_OPS_???");
132 decode_mtd_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
134 struct mtd_info_user minfo;
137 if (umove_or_printaddr(tcp, addr, &minfo))
141 printxval(mtd_type_options, minfo.type, "MTD_???");
143 printflags(mtd_flags_options, minfo.flags, "MTD_???");
144 tprintf(", size=%#x, erasesize=%#x, writesize=%#x, oobsize=%#x"
145 ", padding=%#" PRIx64 "}",
146 minfo.size, minfo.erasesize, minfo.writesize, minfo.oobsize,
147 (uint64_t) minfo.padding);
151 decode_nand_oobinfo(struct tcb *const tcp, const kernel_ulong_t addr)
153 struct nand_oobinfo ninfo;
157 if (umove_or_printaddr(tcp, addr, &ninfo))
161 printxval(mtd_nandecc_options, ninfo.useecc, "MTD_NANDECC_???");
162 tprintf(", eccbytes=%#x", ninfo.eccbytes);
164 tprints(", oobfree={");
165 for (i = 0; i < ARRAY_SIZE(ninfo.oobfree); ++i) {
169 for (j = 0; j < ARRAY_SIZE(ninfo.oobfree[0]); ++j) {
172 tprintf("%#x", ninfo.oobfree[i][j]);
176 tprints("}}, eccpos={");
177 for (i = 0; i < ARRAY_SIZE(ninfo.eccpos); ++i) {
180 tprintf("%#x", ninfo.eccpos[i]);
187 decode_nand_ecclayout_user(struct tcb *const tcp, const kernel_ulong_t addr)
189 struct nand_ecclayout_user nlay;
193 if (umove_or_printaddr(tcp, addr, &nlay))
196 tprintf("{eccbytes=%#x, eccpos={", nlay.eccbytes);
197 for (i = 0; i < ARRAY_SIZE(nlay.eccpos); ++i) {
200 tprintf("%#x", nlay.eccpos[i]);
202 tprintf("}, oobavail=%#x, oobfree={", nlay.oobavail);
203 for (i = 0; i < ARRAY_SIZE(nlay.oobfree); ++i) {
206 tprintf("{offset=%#x, length=%#x}",
207 nlay.oobfree[i].offset, nlay.oobfree[i].length);
213 decode_mtd_ecc_stats(struct tcb *const tcp, const kernel_ulong_t addr)
215 struct mtd_ecc_stats es;
218 if (umove_or_printaddr(tcp, addr, &es))
221 tprintf("{corrected=%#x, failed=%#x, badblocks=%#x, bbtblocks=%#x}",
222 es.corrected, es.failed, es.badblocks, es.bbtblocks);
225 MPERS_PRINTER_DECL(int, mtd_ioctl, struct tcb *const tcp,
226 const unsigned int code, const kernel_ulong_t arg)
233 decode_erase_info_user(tcp, arg);
237 decode_erase_info_user64(tcp, arg);
242 decode_mtd_oob_buf(tcp, arg);
247 decode_mtd_oob_buf64(tcp, arg);
251 decode_mtd_write_req(tcp, arg);
254 case OTPGETREGIONINFO:
257 ATTRIBUTE_FALLTHROUGH;
259 decode_otp_info(tcp, arg);
263 decode_otp_select(tcp, arg);
268 printxval64(mtd_file_mode_options, arg, "MTD_FILE_MODE_???");
274 printnum_int64(tcp, arg, "%" PRIu64);
280 decode_mtd_info_user(tcp, arg);
286 decode_nand_oobinfo(tcp, arg);
292 decode_nand_ecclayout_user(tcp, arg);
298 decode_mtd_ecc_stats(tcp, arg);
301 case OTPGETREGIONCOUNT:
305 printnum_int(tcp, arg, "%u");
308 case MEMGETREGIONCOUNT:
312 printnum_int(tcp, arg, "%d");
315 case MEMGETREGIONINFO:
317 struct region_info_user rinfo;
320 if (umove_or_printaddr(tcp, arg, &rinfo))
322 tprintf("{regionindex=%#x", rinfo.regionindex);
325 struct region_info_user rinfo;
327 if (!syserror(tcp) && !umove(tcp, arg, &rinfo))
328 tprintf(", offset=%#x"
342 return RVAL_IOCTL_DECODED;
345 #endif /* HAVE_STRUCT_MTD_WRITE_REQ */