1 /* 2 * This file is part of ioctl_mtd strace test. 3 * 4 * Copyright (c) 2016 Dmitry V. Levin <ldv (at) altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 32 #include <errno.h> 33 #include <inttypes.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <sys/ioctl.h> 37 #include <linux/ioctl.h> 38 #include <linux/version.h> 39 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) 40 # include "mtd-abi.h" 41 #else 42 # include <mtd/mtd-abi.h> 43 #endif 44 45 static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL; 46 47 #define TEST_NULL_ARG(cmd) \ 48 do { \ 49 ioctl(-1, cmd, 0); \ 50 if (_IOC_DIR(cmd) == _IOC_WRITE) \ 51 printf("ioctl(-1, MIXER_WRITE(%u) or %s, NULL)" \ 52 " = -1 EBADF (%m)\n", \ 53 (unsigned int) _IOC_NR(cmd), #cmd); \ 54 else if (_IOC_DIR(cmd) == _IOC_READ) \ 55 printf("ioctl(-1, MIXER_READ(%u) or %s, NULL)" \ 56 " = -1 EBADF (%m)\n", \ 57 (unsigned int) _IOC_NR(cmd), #cmd); \ 58 else \ 59 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", #cmd); \ 60 } while (0) 61 62 #define TEST_erase_info_user(cmd, eiu) \ 63 ioctl(-1, cmd, eiu); \ 64 printf("ioctl(-1, MIXER_%s(%u) or %s, {start=%#x, length=%#x})" \ 65 " = -1 EBADF (%m)\n", \ 66 (_IOC_DIR(cmd) == _IOC_READ) ? "READ" : "WRITE", \ 67 (unsigned int) _IOC_NR(cmd), #cmd, \ 68 eiu->start, eiu->length) 69 70 int 71 main(void) 72 { 73 TEST_NULL_ARG(ECCGETLAYOUT); 74 TEST_NULL_ARG(ECCGETSTATS); 75 TEST_NULL_ARG(MEMERASE); 76 TEST_NULL_ARG(MEMERASE64); 77 TEST_NULL_ARG(MEMGETBADBLOCK); 78 TEST_NULL_ARG(MEMGETINFO); 79 TEST_NULL_ARG(MEMGETOOBSEL); 80 TEST_NULL_ARG(MEMGETREGIONCOUNT); 81 TEST_NULL_ARG(MEMISLOCKED); 82 TEST_NULL_ARG(MEMLOCK); 83 TEST_NULL_ARG(MEMREADOOB); 84 TEST_NULL_ARG(MEMREADOOB64); 85 TEST_NULL_ARG(MEMSETBADBLOCK); 86 TEST_NULL_ARG(MEMUNLOCK); 87 TEST_NULL_ARG(MEMWRITE); 88 TEST_NULL_ARG(MEMWRITEOOB); 89 TEST_NULL_ARG(MEMWRITEOOB64); 90 TEST_NULL_ARG(OTPGETREGIONCOUNT); 91 TEST_NULL_ARG(OTPGETREGIONINFO); 92 TEST_NULL_ARG(OTPLOCK); 93 TEST_NULL_ARG(OTPSELECT); 94 95 ioctl(-1, MTDFILEMODE, MTD_FILE_MODE_NORMAL); 96 printf("ioctl(-1, MTDFILEMODE, MTD_FILE_MODE_NORMAL) = -1 EBADF (%m)\n"); 97 98 int *const opt = tail_alloc(sizeof(*opt)); 99 *opt = MTD_OTP_OFF; 100 ioctl(-1, OTPSELECT, opt); 101 printf("ioctl(-1, MIXER_READ(%u) or OTPSELECT, [MTD_OTP_OFF])" 102 " = -1 EBADF (%m)\n", (unsigned int) _IOC_NR(OTPSELECT)); 103 104 uint64_t *const v64 = tail_alloc(sizeof(*v64)); 105 fill_memory(v64, sizeof(*v64)); 106 107 ioctl(-1, MEMGETBADBLOCK, v64); 108 printf("ioctl(-1, MIXER_WRITE(%u) or MEMGETBADBLOCK, [%" PRIu64 "])" 109 " = -1 EBADF (%m)\n", 110 (unsigned int) _IOC_NR(MEMGETBADBLOCK), *v64); 111 112 ioctl(-1, MEMSETBADBLOCK, v64); 113 printf("ioctl(-1, MIXER_WRITE(%u) or MEMSETBADBLOCK, [%" PRIu64 "])" 114 " = -1 EBADF (%m)\n", 115 (unsigned int) _IOC_NR(MEMSETBADBLOCK), *v64); 116 117 struct region_info_user *const riu = tail_alloc(sizeof(*riu)); 118 fill_memory(riu, sizeof(*riu)); 119 ioctl(-1, MEMGETREGIONINFO, riu); 120 printf("ioctl(-1, %s, {regionindex=%#x}) = -1 EBADF (%m)\n", 121 "MEMGETREGIONINFO" 122 #ifdef __i386__ 123 " or MTRRIOC_GET_PAGE_ENTRY" 124 #endif 125 , riu->regionindex); 126 127 struct erase_info_user *const eiu = tail_alloc(sizeof(*eiu)); 128 fill_memory(eiu, sizeof(*eiu)); 129 130 TEST_erase_info_user(MEMERASE, eiu); 131 TEST_erase_info_user(MEMLOCK, eiu); 132 TEST_erase_info_user(MEMUNLOCK, eiu); 133 TEST_erase_info_user(MEMISLOCKED, eiu); 134 135 struct erase_info_user64 *const eiu64 = tail_alloc(sizeof(*eiu64)); 136 fill_memory(eiu64, sizeof(*eiu64)); 137 ioctl(-1, MEMERASE64, eiu64); 138 printf("ioctl(-1, MIXER_WRITE(%u) or %s, {start=%#llx, length=%#llx})" 139 " = -1 EBADF (%m)\n", 140 (unsigned int) _IOC_NR(MEMERASE64), "MEMERASE64", 141 (unsigned long long) eiu64->start, 142 (unsigned long long) eiu64->length); 143 144 struct mtd_oob_buf *const oob = tail_alloc(sizeof(*oob)); 145 fill_memory(oob, sizeof(*oob)); 146 147 ioctl(-1, MEMWRITEOOB, oob); 148 printf("ioctl(-1, MEMWRITEOOB, {start=%#x, length=%#x, ptr=%p})" 149 " = -1 EBADF (%m)\n", oob->start, oob->length, oob->ptr); 150 151 ioctl(-1, MEMREADOOB, oob); 152 printf("ioctl(-1, MEMREADOOB, {start=%#x, length=%#x, ptr=%p})" 153 " = -1 EBADF (%m)\n", oob->start, oob->length, oob->ptr); 154 155 struct mtd_oob_buf64 *const oob64 = tail_alloc(sizeof(*oob64)); 156 fill_memory(oob64, sizeof(*oob64)); 157 158 ioctl(-1, MEMWRITEOOB64, oob64); 159 printf("ioctl(-1, MEMWRITEOOB64" 160 ", {start=%#llx, length=%#x, usr_ptr=%#llx}) = -1 EBADF (%m)\n", 161 (unsigned long long) oob64->start, oob64->length, 162 (unsigned long long) oob64->usr_ptr); 163 164 ioctl(-1, MEMREADOOB64, oob64); 165 printf("ioctl(-1, MEMREADOOB64" 166 ", {start=%#llx, length=%#x, usr_ptr=%#llx}) = -1 EBADF (%m)\n", 167 (unsigned long long) oob64->start, oob64->length, 168 (unsigned long long) oob64->usr_ptr); 169 170 171 struct otp_info *const oi = tail_alloc(sizeof(*oi)); 172 fill_memory(oi, sizeof(*oi)); 173 ioctl(-1, OTPLOCK, oi); 174 printf("ioctl(-1, MIXER_READ(%u) or OTPLOCK" 175 ", {start=%#x, length=%#x, locked=%u}) = -1 EBADF (%m)\n", 176 (unsigned int) _IOC_NR(OTPLOCK), oi->start, oi->length, oi->locked); 177 178 struct mtd_write_req *const wr = tail_alloc(sizeof(*wr)); 179 fill_memory(wr, sizeof(*wr)); 180 wr->mode = MTD_OPS_PLACE_OOB; 181 ioctl(-1, MEMWRITE, wr); 182 printf("ioctl(-1, MEMWRITE, {start=%#llx, len=%#llx, ooblen=%#llx" 183 ", usr_data=%#llx, usr_oob=%#llx, mode=MTD_OPS_PLACE_OOB})" 184 " = -1 EBADF (%m)\n", 185 (unsigned long long) wr->start, 186 (unsigned long long) wr->len, 187 (unsigned long long) wr->ooblen, 188 (unsigned long long) wr->usr_data, 189 (unsigned long long) wr->usr_oob); 190 191 ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x4d, 0xfe, 0xff), lmagic); 192 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", 193 "_IOC(_IOC_READ|_IOC_WRITE, 0x4d, 0xfe, 0xff)", lmagic); 194 195 puts("+++ exited with 0 +++"); 196 return 0; 197 } 198