1 #! /bin/sh 2 # Copyright (c) 2001 Wichert Akkerman <wichert (at] cistron.nl> 3 # All rights reserved. 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions 7 # are met: 8 # 1. Redistributions of source code must retain the above copyright 9 # notice, this list of conditions and the following disclaimer. 10 # 2. Redistributions in binary form must reproduce the above copyright 11 # notice, this list of conditions and the following disclaimer in the 12 # documentation and/or other materials provided with the distribution. 13 # 3. The name of the author may not be used to endorse or promote products 14 # derived from this software without specific prior written permission. 15 # 16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 # Validate arg count. 28 case $# in 29 1) 30 dir="$1" 31 asm=asm 32 ;; 33 2) 34 dir="$1" 35 asm="$2" 36 ;; 37 *) 38 echo "usage: $0 include-directory [asm-subdirectory]" >&2 39 exit 1 40 ;; 41 esac 42 43 lookup_ioctls() 44 { 45 type="$1" 46 shift 47 48 # Build the list of all ioctls 49 regexp='^[[:space:]]*#[[:space:]]*define[[:space:]]\+[A-Z][A-Z0-9_]*[[:space:]]\+0x'"$type"'..\>' 50 (cd "$dir" && for f; do grep "$regexp" "$f" "uapi/$f" 2>/dev/null; done) | 51 sed -ne "s,$asm/,asm/,g"' 52 s/^\(.*\):[[:space:]]*#[[:space:]]*define[[:space:]]*\([A-Z0-9_]*\)[[:space:]]*\(0x'"$type"'..\).*/ { "\1", "\2", \3 },/p' \ 53 >> ioctls.h 54 } 55 56 > ioctls.h 57 58 lookup_ioctls 03 linux/hdreg.h 59 lookup_ioctls 22 scsi/sg.h 60 lookup_ioctls 46 linux/fb.h 61 lookup_ioctls 4B linux/kd.h 62 lookup_ioctls 4C linux/loop.h 63 lookup_ioctls 53 linux/cdrom.h scsi/scsi.h scsi/scsi_ioctl.h 64 lookup_ioctls 54 $asm/ioctls.h asm-generic/ioctls.h 65 lookup_ioctls 56 linux/vt.h 66 lookup_ioctls '7[12]' linux/videotext.h 67 lookup_ioctls 89 $asm/sockios.h asm-generic/sockios.h linux/sockios.h 68 lookup_ioctls 8B linux/wireless.h 69 70 if [ -e $dir/Kbuild ]; then 71 # kernel has exported user space headers, so query only them 72 files=$( 73 cd $dir || exit 74 find . -mindepth 2 -name Kbuild | \ 75 sed -e 's:^\./::' -e 's:/Kbuild:/*:' | \ 76 grep -v '^asm-' 77 echo "$asm/* asm-generic/*" 78 ) 79 # special case: some headers aren't exported directly 80 files="${files} media/* net/bluetooth/* pcmcia/*" 81 else 82 # older kernel so just assume some headers 83 files="linux/* $asm/* asm-generic/* scsi/* sound/*" 84 fi 85 86 # Build the list of all ioctls 87 # Example output: 88 # { "asm/ioctls.h", "TIOCSWINSZ", 0x5414 }, 89 # { "asm/mce.h", "MCE_GETCLEAR_FLAGS", _IOC(_IOC_NONE,'M',3,0) }, 90 regexp='^[[:space:]]*#[[:space:]]*define[[:space:]]\+[A-Z][A-Z0-9_]*[[:space:]]\+_S\?\(IO\|IOW\|IOR\|IOWR\)\>' 91 (cd $dir && grep $regexp $files 2>/dev/null) | \ 92 sed -n \ 93 -e "s,$asm/,asm/,g" \ 94 -e 's/^\(.*\):[[:space:]]*#[[:space:]]*define[[:space:]]*\([A-Z0-9_]*\)[[:space:]]*_S\?I.*(\([^[,]*\)[[:space:]]*,[[:space:]]*\([^,)]*\).*/ { "\1", "\2", _IOC(_IOC_NONE,\3,\4,0) },/p' \ 95 >> ioctls.h 96 97 # Strip uapi/ prefix 98 sed -i 's|"uapi/|"|' ioctls.h 99 100 # Sort and drop dups 101 sort -u -o ioctls.h ioctls.h 102 103 > ioctldefs.h 104 105 # Collect potential ioctl names. ('bases' is a bad name. Sigh) 106 # Some use a special base to offset their ioctls on. Extract that as well. 107 # Some use 2 defines: _IOC(_IOC_NONE,DM_IOCTL,DM_LIST_DEVICES_CMD,....) 108 bases=$(sed -n \ 109 -e 's/.*_IOC_NONE.*,[[:space:]]*\([A-Z][A-Z0-9_]\+\)[[:space:]]*,[[:space:]]*\([A-Z][A-Z0-9_]\+\)[[:space:]+,].*/\1\n\2/p' \ 110 -e 's/.*_IOC_NONE.*,[[:space:]]*\([A-Z][A-Z0-9_]\+\)[[:space:]+,].*/\1/p' \ 111 ioctls.h | sort -u) 112 113 for base in $bases; do 114 echo "Looking for $base" 115 regexp="^[[:space:]]*#[[:space:]]*define[[:space:]]\+$base" 116 line=$( (cd $dir && grep -h $regexp 2>/dev/null $files) | grep -v '\<_IO') 117 if [ x"$line" != x ]; then 118 echo "$base is a #define" # "($line)" 119 echo "$line" >> ioctldefs.h 120 fi 121 122 if ! grep "\<$base\>" ioctldefs.h >/dev/null 2>/dev/null; then 123 # Not all ioctl's are defines ... some (like the DM_* stuff) 124 # are enums, so we have to extract that crap ourself 125 ( 126 cd $dir || exit 127 # -P: inhibit generation of linemarkers 128 ${CPP:-cpp} -P $(grep -l $base $files 2>/dev/null) | sed '/^$/d' | \ 129 awk -v base="$base" '{ 130 if ($1 == "enum") { 131 val = 0 132 while ($NF != "};") { 133 if (!getline) 134 exit 135 gsub(/,/, "") 136 if ($0 ~ /=/) 137 val = $NF 138 if ($1 == base) { 139 print "#define " base " (" val ")" 140 exit 141 } 142 val++ 143 } 144 } 145 }' 146 ) >> ioctldefs.h 147 if ! grep "\<$base\>" ioctldefs.h >/dev/null 2>/dev/null; then 148 echo "Can't find the definition for $base" 149 else 150 echo "$base is an enum" 151 fi 152 fi 153 done 154 155 # Sort and drop dups? 156 # sort -u <ioctldefs.h >ioctldefs1.h && mv ioctldefs1.h ioctldefs.h 157