linux/drivers/char/raw.c
<<
alue2alue2al//spa3.1al/spa3 class="lxr_search">aluealue2alue2alue2typ Searchalue2al//spa3.1ue2< al/input typ aue2< 1 /div id < <1//a>/spa3 class="comment">/*//spa3.1< <2//a>/spa3 class="comment"> * linux/drivers/char/raw.c//spa3.1< <3//a>/spa3 class="comment"> *//spa3.1< <4//a>/spa3 class="comment"> * Front-end raw charac er devices. These ca3 be bound to any block//spa3.1< <5//a>/spa3 class="comment"> * devices to provide genuine Unix raw charac er device semantics.//spa3.1< <6//a>/spa3 class="comment"> *//spa3.1< <7//a>/spa3 class="comment"> * We reserve minor number 0 for a control interface. ioctl()s on>this//spa3.1< <8//a>/spa3 class="comment"> * device are used to bind the other minor numbers to block devices.//spa3.1< <9//a>/spa3 class="comment"> *///spa3.1< a.1< 11//a>#include <linux/init.h//a>>1< 12//a>#include <linux/fs.h//a>>1< 13//a>#include <linux/major.h//a>>1< 14//a>#include <linux/blkdev.h//a>>1< 15//a>#include <linux/module.h//a>>1< 16//a>#include <linux/raw.h//a>>1< 17//a>#include <linux/capability.h//a>>1< 18//a>#include <linux/uio.h//a>>1< 19//a>#include <linux/cdev.h//a>>1< 20//a>#include <linux/device.h//a>>1< 21//a>#include <linux/mutex.h//a>>1< 22//a>#include <linux/gfp.h//a>>1< 23//a>#include <linux/compat.h//a>>1< 24//a>#include <linux/vmalloc.h//a>>1< 25 a.1< 26//a>#include <asm/uaccess.h//a>>1< 27 a.1< 28//a>structraw_device_data//a> {1< 29//a> structblock_device//a> */a href="+code=binding" class="sref">binding//a>;1< 30//a> intinuse//a>;1< 31//a>};1< 32 a.1< 33//a>static structclass//a> */a href="+code=raw_class" class="sref">raw_class//a>;1< 34//a>static structraw_device_data//a> */a href="+code=raw_devices" class="sref">raw_devices//a>;1< 35//a>static /a href="+code=DEFINE_MUTEX" class="sref">DEFINE_MUTEX//a>(/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1< 36//a>static const structfile_opera v3s//a> /a href="+code=raw_ctl_fops" class="sref">raw_ctl_fops//a>; /spa3 class="comment">/* forward declara v3 *///spa3.1< 37 a.1< 38//a>static intmax_raw_minors//a> =MAX_RAW_MINORS//a>;1< 39 a.1< 40//a>/a href="+code=module_param" class="sref">module_param//a>(/a href="+code=max_raw_minors" class="sref">max_raw_minors//a>, int, 0);1< 41//a>/a href="+code=MODULE_PARM_DESC" class="sref">MODULE_PARM_DESC//a>(/a href="+code=max_raw_minors" class="sref">max_raw_minors//a>, /spa3 class="string">"Maximum number of raw devices (1-65536)"//spa3.);1< 42 a.1< 43//a>/spa3 class="comment">/*//spa3.1< 44//a>/spa3 class="comment"> * Open/close code for raw IO.//spa3.1< 45//a>/spa3 class="comment"> *//spa3.1< 46//a>/spa3 class="comment"> * We just rewrite the i_mapping for the /dev/raw/rawN file descriptor to//spa3.1< 47//a>/spa3 class="comment"> * point< 48//a>/spa3 class="comment"> * O_DIRECT.//spa3.1< 49//a>/spa3 class="comment"> *//spa3.1< 50//a>/spa3 class="comment"> * Set the device's soft blocksize to the minimum possible. This gives the//spa3.1< 51//a>/spa3 class="comment"> * finest possible alignment and has no adverse impact on>performance.//spa3.1< 52//a>/spa3 class="comment"> *///spa3.1< 53//a>static intraw_open//a>(structinode//a> */a href="+code=inode" class="sref">inode//a>, structfile//a> */a href="+code=filp" class="sref">filp//a>)1< 54//a>{1< 55//a> const intminor//a> =iminor//a>(/a href="+code=inode" class="sref">inode//a>);1< 56//a> structblock_device//a> */a href="+code=bdev" class="sref">bdev//a>;1< 57//a> interr//a>;1< 58 a.1< 59//a> if (/a href="+code=minor" class="sref">minor//a> == 0) { /spa3 class="comment">/* It is the control device *///spa3.1< 60//a> /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_op" class="sref">f_op//a> =<&/a href="+code=raw_ctl_fops" class="sref">raw_ctl_fops//a>;1< 61//a> return 0;1< 62//a> }1< 63 a.1< 64//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1< 65 a.1< 66//a> /spa3 class="comment">/*//spa3.1< 67//a>/spa3 class="comment"> * All we need to do on>open is check that the device is bound.//spa3.1< 68//a>/spa3 class="comment"> *///spa3.1< 69//a> /a href="+code=bdev" class="sref">bdev//a> =raw_devices//a>[/a href="+code=minor" class="sref">minor//a>]./a href="+code=binding" class="sref">binding//a>;1< 70//a> /a href="+code=err" class="sref">err//a> =<-/a href="+code=ENODEV" class="sref">ENODEV//a>;1< 71//a> if (!/a href="+code=bdev" class="sref">bdev//a>)1< 72//a> goto /a href="+code=out" class="sref">out//a>;1< 73//a> /a href="+code=igrab" class="sref">igrab//a>(/a href="+code=bdev" class="sref">bdev//a>->/a href="+code=bd_inode" class="sref">bd_inode//a>);1< 74//a> /a href="+code=err" class="sref">err//a> =blkdev_get//a>(/a href="+code=bdev" class="sref">bdev//a>, /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_mode" class="sref">f_mode//a> | /a href="+code=FMODE_EXCL" class="sref">FMODE_EXCL//a>, /a href="+code=raw_open" class="sref">raw_open//a>);1< 75//a> if (/a href="+code=err" class="sref">err//a>)1< 76//a> goto /a href="+code=out" class="sref">out//a>;1< 77//a> /a href="+code=err" class="sref">err//a> =set_blocksize//a>(/a href="+code=bdev" class="sref">bdev//a>, /a href="+code=bdev_logical_block_size" class="sref">bdev_logical_block_size//a>(/a href="+code=bdev" class="sref">bdev//a>));1< 78//a> if (/a href="+code=err" class="sref">err//a>)1< 79//a> goto /a href="+code=out1" class="sref">out1//a>;1< 80//a> /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_flags" class="sref">f_flags//a> |=O_DIRECT//a>;1< 81//a> /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_mapping" class="sref">f_mapping//a> =bdev//a>->/a href="+code=bd_inode" class="sref">bd_inode//a>->/a href="+code=i_mapping" class="sref">i_mapping//a>;1< 82//a> if (++/a href="+code=raw_devices" class="sref">raw_devices//a>[/a href="+code=minor" class="sref">minor//a>]./a href="+code=inuse" class="sref">inuse//a> == 1)1< 83//a> /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_path" class="sref">f_path//a>./a href="+code=dentry" class="sref">dentry//a>->/a href="+code=d_inode" class="sref">d_inode//a>->/a href="+code=i_mapping" class="sref">i_mapping//a> =1< 84//a> /a href="+code=bdev" class="sref">bdev//a>->/a href="+code=bd_inode" class="sref">bd_inode//a>->/a href="+code=i_mapping" class="sref">i_mapping//a>;1< 85//a> /a href="+code=filp" class="sref">filp//a>->/a href="+code=private_data" class="sref">private_data//a> =bdev//a>;1< 86//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1< 87//a> return 0;1< 88 a.1< 89//a>/a href="+code=out1" class="sref">out1//a>:1< 90//a> /a href="+code=blkdev_put" class="sref">blkdev_put//a>(/a href="+code=bdev" class="sref">bdev//a>, /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_mode" class="sref">f_mode//a> | /a href="+code=FMODE_EXCL" class="sref">FMODE_EXCL//a>);1< 91//a>/a href="+code=out" class="sref">out//a>:1< 92//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1< 93//a> return /a href="+code=err" class="sref">err//a>;1< 94//a>}1< 95 a.1< 96//a>/spa3 class="comment">/*//spa3.1< 97//a>/spa3 class="comment"> * When the final fd which refers to this charac er-special node is closed, we//spa3.1< 98//a>/spa3 class="comment"> * make its ->mapping point< 99//a>/spa3 class="comment"> *///spa3.1<100//a>static intraw_release//a>(structinode//a> */a href="+code=inode" class="sref">inode//a>, structfile//a> */a href="+code=filp" class="sref">filp//a>)1<101//a>{1<102//a> const intminor//a>=iminor//a>(/a href="+code=inode" class="sref">inode//a>);1<103//a> structblock_device//a> */a href="+code=bdev" class="sref">bdev//a>;1<104 a.1<105//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<106//a> /a href="+code=bdev" class="sref">bdev//a> =raw_devices//a>[/a href="+code=minor" class="sref">minor//a>]./a href="+code=binding" class="sref">binding//a>;1<107//a> if (--/a href="+code=raw_devices" class="sref">raw_devices//a>[/a href="+code=minor" class="sref">minor//a>]./a href="+code=inuse" class="sref">inuse//a> == 0) {1<108//a> /spa3 class="comment">/* Here inode->i_mapping == bdev->bd_inode->i_mapping *///spa3.1<109//a> /a href="+code=inode" class="sref">inode//a>->/a href="+code=i_mapping" class="sref">i_mapping//a> =<&/a href="+code=inode" class="sref">inode//a>->/a href="+code=i_data" class="sref">i_data//a>;1<110//a> /a href="+code=inode" class="sref">inode//a>->/a href="+code=i_mapping" class="sref">i_mapping//a>->/a href="+code=backing_dev_info" class="sref">backing_dev_info//a> =<&/a href="+code=default_backing_dev_info" class="sref">default_backing_dev_info//a>;1<111//a> }1<112//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<113 a.1<114//a> /a href="+code=blkdev_put" class="sref">blkdev_put//a>(/a href="+code=bdev" class="sref">bdev//a>, /a href="+code=filp" class="sref">filp//a>->/a href="+code=f_mode" class="sref">f_mode//a> | /a href="+code=FMODE_EXCL" class="sref">FMODE_EXCL//a>);1<115//a> return 0;1<116//a>}1<117 a.1<118//a>/spa3 class="comment">/*//spa3.1<119//a>/spa3 class="comment"> * Forward ioctls to the underlying block device.//spa3.1<120//a>/spa3 class="comment"> *///spa3.1<121//a>static long1<122//a>/a href="+code=raw_ioctl" class="sref">raw_ioctl//a>(structfile//a> */a href="+code=filp" class="sref">filp//a>, unsigned intcommand//a>, unsigned longarg//a>)1<123//a>{1<124//a> structblock_device//a> */a href="+code=bdev" class="sref">bdev//a> =filp//a>->/a href="+code=private_data" class="sref">private_data//a>;1<125//a> return /a href="+code=blkdev_ioctl" class="sref">blkdev_ioctl//a>(/a href="+code=bdev" class="sref">bdev//a>, 0, /a href="+code=command" class="sref">command//a>, /a href="+code=arg" class="sref">arg//a>);1<126//a>}1<127 a.1<128//a>static intbind_set//a>(intnumber//a>, /a href="+code=u64" class="sref">u64//a> /a href="+code=major" class="sref">major//a>, /a href="+code=u64" class="sref">u64//a> /a href="+code=minor" class="sref">minor//a>)1<129//a>{1<130//a> /a href="+code=dev_t" class="sref">dev_t//a> /a href="+code=dev" class="sref">dev//a> =MKDEV//a>(/a href="+code=major" class="sref">major//a>, /a href="+code=minor" class="sref">minor//a>);1<131//a> structraw_device_data//a> */a href="+code=rawdev" class="sref">rawdev//a>;1<132//a> interr//a> =<0;1<133 a.1<134//a> if (/a href="+code=number" class="sref">number//a> <=<0 || /a href="+code=number" class="sref">number//a> >=max_raw_minors//a>)1<135//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<136//a>1<137//a> if (/a href="+code=MAJOR" class="sref">MAJOR//a>(/a href="+code=dev" class="sref">dev//a>) !=major//a> || /a href="+code=MINOR" class="sref">MINOR//a>(/a href="+code=dev" class="sref">dev//a>) !=minor//a>)1<138//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<139 a.1<140//a> /a href="+code=rawdev" class="sref">rawdev//a> =<&/a href="+code=raw_devices" class="sref">raw_devices//a>[/a href="+code=number" class="sref">number//a>];1<141//a>1<142//a> /spa3 class="comment">/*//spa3.1<143//a>/spa3 class="comment"> * This is like making block devices, so demand the//spa3.1<144//a>/spa3 class="comment"> * sam capability//spa3.1<145//a>/spa3 class="comment"> *///spa3.1<146//a> if (!/a href="+code=capable" class="sref">capable//a>(/a href="+code=CAP_SYS_ADMIN" class="sref">CAP_SYS_ADMIN//a>))1<147//a> return -/a href="+code=EPERM" class="sref">EPERM//a>;1<148 a.1<149//a> /spa3 class="comment">/*//spa3.1<150//a>/spa3 class="comment"> * For now, we don't need to check that the underlying//spa3.1<151//a>/spa3 class="comment"> * block device is present<152//a>/spa3 class="comment"> * the raw device is opened. Just check that the//spa3.1<153//a>/spa3 class="comment"> * major/minor numbers make sense.//spa3.1<154//a>/spa3 class="comment"> *///spa3.1<155 a.1<156//a> if (/a href="+code=MAJOR" class="sref">MAJOR//a>(/a href="+code=dev" class="sref">dev//a>) == 0<&& /a href="+code=dev" class="sref">dev//a> != 0)1<157//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<158 a.1<159//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<160//a> if (/a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=inuse" class="sref">inuse//a>) {1<161//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<162//a> return -/a href="+code=EBUSY" class="sref">EBUSY//a>;1<163//a> }1<164//a> if (/a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=binding" class="sref">binding//a>) {1<165//a> /a href="+code=bdput" class="sref">bdput//a>(/a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=binding" class="sref">binding//a>);1<166//a> /a href="+code=module_put" class="sref">module_put//a>(/a href="+code=THIS_MODULE" class="sref">THIS_MODULE//a>);1<167//a> }1<168//a> if (!/a href="+code=dev" class="sref">dev//a>) {1<169//a> /spa3 class="comment">/* unbind *///spa3.1<170//a> /a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=binding" class="sref">binding//a> =NULL//a>;1<171//a> /a href="+code=device_destroy" class="sref">device_destroy//a>(/a href="+code=raw_class" class="sref">raw_class//a>, /a href="+code=MKDEV" class="sref">MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, /a href="+code=number" class="sref">number//a>));1<172//a> } else {1<173//a> /a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=binding" class="sref">binding//a> =bdget//a>(/a href="+code=dev" class="sref">dev//a>);1<174//a> if (/a href="+code=rawdev" class="sref">rawdev//a>->/a href="+code=binding" class="sref">binding//a> == /a href="+code=NULL" class="sref">NULL//a>) {1<175//a> /a href="+code=err" class="sref">err//a> =<-/a href="+code=ENOMEM" class="sref">ENOMEM//a>;1<176//a> } else {1<177//a> /a href="+code=dev_t" class="sref">dev_t//a> /a href="+code=raw" class="sref">raw//a> =MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, /a href="+code=number" class="sref">number//a>);1<178//a> /a href="+code=__module_get" class="sref">__module_get//a>(/a href="+code=THIS_MODULE" class="sref">THIS_MODULE//a>);1<179//a> /a href="+code=device_destroy" class="sref">device_destroy//a>(/a href="+code=raw_class" class="sref">raw_class//a>, /a href="+code=raw" class="sref">raw//a>);1<180//a> /a href="+code=device_create" class="sref">device_create//a>(/a href="+code=raw_class" class="sref">raw_class//a>, /a href="+code=NULL" class="sref">NULL//a>, /a href="+code=raw" class="sref">raw//a>, /a href="+code=NULL" class="sref">NULL//a>,1<181//a> /spa3 class="string">"raw%d"//spa3., /a href="+code=number" class="sref">number//a>);1<182//a> }1<183//a> }1<184//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<185//a> return /a href="+code=err" class="sref">err//a>;1<186//a>}1<187 a.1<188//a>static intbind_get//a>(intnumber//a>, /a href="+code=dev_t" class="sref">dev_t//a> */a href="+code=dev" class="sref">dev//a>)1<189//a>{1<190//a> structraw_device_data//a> */a href="+code=rawdev" class="sref">rawdev//a>;1<191//a> structblock_device//a> */a href="+code=bdev" class="sref">bdev//a>;1<192 a.1<193//a> if (/a href="+code=number" class="sref">number//a> <=<0 || /a href="+code=number" class="sref">number//a> >=MAX_RAW_MINORS//a>)1<194//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<195 a.1<196//a> /a href="+code=rawdev" class="sref">rawdev//a> =<&/a href="+code=raw_devices" class="sref">raw_devices//a>[/a href="+code=number" class="sref">number//a>];1<197 a.1<198//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<199//a> /a href="+code=bdev" class="sref">bdev//a> =rawdev//a>->/a href="+code=binding" class="sref">binding//a>;1<200//a> */a href="+code=dev" class="sref">dev//a> =bdev//a> ? /a href="+code=bdev" class="sref">bdev//a>->/a href="+code=bd_dev" class="sref">bd_dev//a> :<0;1<201//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=raw_mutex" class="sref">raw_mutex//a>);1<202//a> return 0;1<203//a>}1<204 a.1<205//a>/spa3 class="comment">/*//spa3.1<206//a>/spa3 class="comment"> * Deal with ioctls against the raw-device control interface, to bind//spa3.1<207//a>/spa3 class="comment"> * and unbind other raw devices.//spa3.1<208//a>/spa3 class="comment"> *///spa3.1<209//a>static long /a href="+code=raw_ctl_ioctl" class="sref">raw_ctl_ioctl//a>(structfile//a> */a href="+code=filp" class="sref">filp//a>, unsigned intcommand//a>,1<210//a> unsigned longarg//a>)1<211//a>{1<212//a> structraw_config_request//a> /a href="+code=rq" class="sref">rq//a>;1<213//a> /a href="+code=dev_t" class="sref">dev_t//a> /a href="+code=dev" class="sref">dev//a>;1<214//a> interr//a>;1<215 a.1<216//a> switch (/a href="+code=command" class="sref">command//a>) {1<217//a> caseRAW_SETBIND//a>:1<218//a> if (/a href="+code=copy_from_user" class="sref">copy_from_user//a>(&/a href="+code=rq" class="sref">rq//a>, (void /a href="+code=__user" class="sref">__user//a> *)arg//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<219//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<220//a>1<221//a> return /a href="+code=bind_set" class="sref">bind_set//a>(/a href="+code=rq" class="sref">rq//a>./a href="+code=raw_minor" class="sref">raw_minor//a>, /a href="+code=rq" class="sref">rq//a>./a href="+code=block_major" class="sref">block_major//a>, /a href="+code=rq" class="sref">rq//a>./a href="+code=block_minor" class="sref">block_minor//a>);1<222 a.1<223//a> caseRAW_GETBIND//a>:1<224//a> if (/a href="+code=copy_from_user" class="sref">copy_from_user//a>(&/a href="+code=rq" class="sref">rq//a>, (void /a href="+code=__user" class="sref">__user//a> *)arg//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<225//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<226//a>1<227//a> /a href="+code=err" class="sref">err//a> =bind_get//a>(/a href="+code=rq" class="sref">rq//a>./a href="+code=raw_minor" class="sref">raw_minor//a>, &/a href="+code=dev" class="sref">dev//a>);1<228//a> if (/a href="+code=err" class="sref">err//a>)1<229//a> return /a href="+code=err" class="sref">err//a>;1<230//a>1<231//a> /a href="+code=rq" class="sref">rq//a>./a href="+code=block_major" class="sref">block_major//a> =MAJOR//a>(/a href="+code=dev" class="sref">dev//a>);1<232//a> /a href="+code=rq" class="sref">rq//a>./a href="+code=block_minor" class="sref">block_minor//a> =MINOR//a>(/a href="+code=dev" class="sref">dev//a>);1<233 a.1<234//a> if (/a href="+code=copy_to_user" class="sref">copy_to_user//a>((void /a href="+code=__user" class="sref">__user//a> *)/a href="+code=arg" class="sref">arg//a>, &/a href="+code=rq" class="sref">rq//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<235//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<236//a>1<237//a> return 0;1<238//a> }1<239 a.1<240//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<241//a>}1<242 a.1<243//a>#ifdef /a href="+code=CONFIG_COMPAT" class="sref">CONFIG_COMPAT a.1<244//a>structraw32_config_request//a> {1<245//a> /a href="+code=compat_int_t" class="sref">compat_int_t//a> /a href="+code=raw_minor" class="sref">raw_minor//a>;1<246//a> /a href="+code=compat_u64" class="sref">compat_u64//a> /a href="+code=block_major" class="sref">block_major//a>;1<247//a> /a href="+code=compat_u64" class="sref">compat_u64//a> /a href="+code=block_minor" class="sref">block_minor//a>;1<248 a.};1<249 a.1<250//a>static long /a href="+code=raw_ctl_compat_ioctl" class="sref">raw_ctl_compat_ioctl//a>(structfile//a> */a href="+code=file" class="sref">file//a>, unsigned intcmd//a>,1<251//a> unsigned longarg//a>)1<252//a>{1<253//a> structraw32_config_request//a> /a href="+code=__user" class="sref">__user//a> */a href="+code=user_req" class="sref">user_req//a> =compat_ptr//a>(/a href="+code=arg" class="sref">arg//a>);1<254//a> structraw32_config_request//a> /a href="+code=rq" class="sref">rq//a>;1<255//a> /a href="+code=dev_t" class="sref">dev_t//a> /a href="+code=dev" class="sref">dev//a>;1<256//a> interr//a> =<0;1<257 a.1<258//a> switch (/a href="+code=cmd" class="sref">cmd//a>) {1<259//a> caseRAW_SETBIND//a>:1<260//a> if (/a href="+code=copy_from_user" class="sref">copy_from_user//a>(&/a href="+code=rq" class="sref">rq//a>, /a href="+code=user_req" class="sref">user_req//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<261//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<262 a.1<263//a> return /a href="+code=bind_set" class="sref">bind_set//a>(/a href="+code=rq" class="sref">rq//a>./a href="+code=raw_minor" class="sref">raw_minor//a>, /a href="+code=rq" class="sref">rq//a>./a href="+code=block_major" class="sref">block_major//a>, /a href="+code=rq" class="sref">rq//a>./a href="+code=block_minor" class="sref">block_minor//a>);1<264 a.1<265//a> caseRAW_GETBIND//a>:1<266//a> if (/a href="+code=copy_from_user" class="sref">copy_from_user//a>(&/a href="+code=rq" class="sref">rq//a>, /a href="+code=user_req" class="sref">user_req//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<267//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<268 a.1<269//a> /a href="+code=err" class="sref">err//a> =bind_get//a>(/a href="+code=rq" class="sref">rq//a>./a href="+code=raw_minor" class="sref">raw_minor//a>, &/a href="+code=dev" class="sref">dev//a>);1<270//a> if (/a href="+code=err" class="sref">err//a>)1<271//a> return /a href="+code=err" class="sref">err//a>;1<272 a.1<273//a> /a href="+code=rq" class="sref">rq//a>./a href="+code=block_major" class="sref">block_major//a> =MAJOR//a>(/a href="+code=dev" class="sref">dev//a>);1<274//a> /a href="+code=rq" class="sref">rq//a>./a href="+code=block_minor" class="sref">block_minor//a> =MINOR//a>(/a href="+code=dev" class="sref">dev//a>);1<275 a.1<276//a> if (/a href="+code=copy_to_user" class="sref">copy_to_user//a>(/a href="+code=user_req" class="sref">user_req//a>, &/a href="+code=rq" class="sref">rq//a>, sizeof(/a href="+code=rq" class="sref">rq//a>)))1<277//a> return -/a href="+code=EFAULT" class="sref">EFAULT//a>;1<278 a.1<279//a> return 0;1<280//a> }1<281//a>1<282//a> return -/a href="+code=EINVAL" class="sref">EINVAL//a>;1<283//a>}1<284//a>#endif1<285 a.1<286//a>static const structfile_operations//a> /a href="+code=raw_fops" class="sref">raw_fops//a> =<{1<287//a> ./a href="+code=read" class="sref">read//a> =do_sync_read//a>,1<288//a> ./a href="+code=aio_read" class="sref">aio_read//a> =generic_file_aio_read//a>,1<289//a> ./a href="+code=write" class="sref">write//a> =do_sync_write//a>,1<290//a> ./a href="+code=aio_write" class="sref">aio_write//a> =blkdev_aio_write//a>,1<291//a> ./a href="+code=fsync" class="sref">fsync//a> =blkdev_fsync//a>,1<292//a> ./a href="+code=open" class="sref">open//a> =raw_open//a>,1<293//a> ./a href="+code=release" class="sref">release//a> =raw_release//a>,1<294//a> ./a href="+code=unlocked_ioctl" class="sref">unlocked_ioctl//a> =raw_ioctl//a>,1<295//a> ./a href="+code=llseek" class="sref">llseek//a> =default_llseek//a>,1<296//a> ./a href="+code=owner" class="sref">owner//a> =THIS_MODULE//a>,1<297 a.};1<298 a.1<299//a>static const structfile_operations//a> /a href="+code=raw_ctl_fops" class="sref">raw_ctl_fops//a> =<{1<300//a> ./a href="+code=unlocked_ioctl" class="sref">unlocked_ioctl//a> =raw_ctl_ioctl//a>,1<301//a>#ifdef /a href="+code=CONFIG_COMPAT" class="sref">CONFIG_COMPAT a.1<302//a> ./a href="+code=compat_ioctl" class="sref">compat_ioctl//a> =raw_ctl_compat_ioctl//a>,1<303//a>#endif1<304//a> ./a href="+code=open" class="sref">open//a> =raw_open//a>,1<305//a> ./a href="+code=owner" class="sref">owner//a> =THIS_MODULE//a>,1<306//a> ./a href="+code=llseek" class="sref">llseek//a> =noop_llseek//a>,1<307 a.};1<308 a.1<309//a>static structcdev//a> /a href="+code=raw_cdev" class="sref">raw_cdev//a>;1<310//a>1<311//a>static char */a href="+code=raw_devnode" class="sref">raw_devnode//a>(structdevice//a> */a href="+code=dev" class="sref">dev//a>, /a href="+code=umode_t" class="sref">umode_t//a> */a href="+code=mode" class="sref">mode//a>)1<312//a>{1<313//a> return /a href="+code=kasprintf" class="sref">kasprintf//a>(/a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL//a>, /spa3 class="string">"raw/%s"//spa3., /a href="+code=dev_nam " class="sref">dev_nam //a>(/a href="+code=dev" class="sref">dev//a>));1<314//a>}1<315 a.1<316//a>static int__init//a> /a href="+code=raw_init" class="sref">raw_init//a>(void)1<317//a>{1<318//a> /a href="+code=dev_t" class="sref">dev_t//a> /a href="+code=dev" class="sref">dev//a> =MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, 0);1<319//a> intret//a>;1<320//a>1<321//a> if (/a href="+code=max_raw_minors" class="sref">max_raw_minors//a> < 1 || /a href="+code=max_raw_minors" class="sref">max_raw_minors//a> > 65536) {1<322//a> /a href="+code=printk" class="sref">printk//a>(/a href="+code=KERN_WARNING" class="sref">KERN_WARNING//a> /spa3 class="string">"raw: invalid max_raw_minors (must be"//spa3.1<323//a> /spa3 class="string">" between 1 and 65536), using %d\n"//spa3., /a href="+code=MAX_RAW_MINORS" class="sref">MAX_RAW_MINORS//a>);1<324//a> /a href="+code=max_raw_minors" class="sref">max_raw_minors//a> =MAX_RAW_MINORS//a>;1<325//a> }1<326//a>1<327//a> /a href="+code=raw_devices" class="sref">raw_devices//a> =vzalloc//a>(sizeof(structraw_device_data//a>) * /a href="+code=max_raw_minors" class="sref">max_raw_minors//a>);1<328//a> if (!/a href="+code=raw_devices" class="sref">raw_devices//a>) {1<329//a> /a href="+code=printk" class="sref">printk//a>(/a href="+code=KERN_ERR" class="sref">KERN_ERR//a> /spa3 class="string">"Not enough memory for raw device structures\n"//spa3.);1<330//a> /a href="+code=ret" class="sref">ret//a> =<-/a href="+code=ENOMEM" class="sref">ENOMEM//a>;1<331//a> goto /a href="+code=error" class="sref">error//a>;1<332//a> }1<333 a.1<334//a> /a href="+code=ret" class="sref">ret//a> =register_chrdev_region//a>(/a href="+code=dev" class="sref">dev//a>, /a href="+code=max_raw_minors" class="sref">max_raw_minors//a>, /spa3 class="string">"raw"//spa3.);1<335//a> if (/a href="+code=ret" class="sref">ret//a>)1<336//a> goto /a href="+code=error" class="sref">error//a>;1<337 a.1<338//a> /a href="+code=cdev_init" class="sref">cdev_init//a>(&/a href="+code=raw_cdev" class="sref">raw_cdev//a>, &/a href="+code=raw_fops" class="sref">raw_fops//a>);1<339//a> /a href="+code=ret" class="sref">ret//a> =cdev_add//a>(&/a href="+code=raw_cdev" class="sref">raw_cdev//a>, /a href="+code=dev" class="sref">dev//a>, /a href="+code=max_raw_minors" class="sref">max_raw_minors//a>);1<340//a> if (/a href="+code=ret" class="sref">ret//a>) {1<341//a> goto /a href="+code=error_region" class="sref">error_region//a>;1<342//a> }1<343 a.1<344//a> /a href="+code=raw_class" class="sref">raw_class//a> =class_create//a>(/a href="+code=THIS_MODULE" class="sref">THIS_MODULE//a>, /spa3 class="string">"raw"//spa3.);1<345//a> if (/a href="+code=IS_ERR" class="sref">IS_ERR//a>(/a href="+code=raw_class" class="sref">raw_class//a>)) {1<346//a> /a href="+code=printk" class="sref">printk//a>(/a href="+code=KERN_ERR" class="sref">KERN_ERR//a> /spa3 class="string">"Error creating raw class.\n"//spa3.);1<347//a> /a href="+code=cdev_del" class="sref">cdev_del//a>(&/a href="+code=raw_cdev" class="sref">raw_cdev//a>);1<348//a> /a href="+code=ret" class="sref">ret//a> =PTR_ERR//a>(/a href="+code=raw_class" class="sref">raw_class//a>);1<349//a> goto /a href="+code=error_region" class="sref">error_region//a>;1<350//a> }1<351//a> /a href="+code=raw_class" class="sref">raw_class//a>->/a href="+code=devnode" class="sref">devnode//a> =raw_devnode//a>;1<352//a> /a href="+code=device_create" class="sref">device_create//a>(/a href="+code=raw_class" class="sref">raw_class//a>, /a href="+code=NULL" class="sref">NULL//a>, /a href="+code=MKDEV" class="sref">MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, 0), /a href="+code=NULL" class="sref">NULL//a>, /spa3 class="string">"rawctl"//spa3.);1<353 a.1<354//a> return 0;1<355 a.1<356//a>/a href="+code=error_region" class="sref">error_region//a>:1<357//a> /a href="+code=unregister_chrdev_region" class="sref">unregister_chrdev_region//a>(/a href="+code=dev" class="sref">dev//a>, /a href="+code=max_raw_minors" class="sref">max_raw_minors//a>);1<358//a>/a href="+code=error" class="sref">error//a>:1<359//a> /a href="+code=vfree" class="sref">vfree//a>(/a href="+code=raw_devices" class="sref">raw_devices//a>);1<360//a> return /a href="+code=ret" class="sref">ret//a>;1<361//a>}1<362 a.1<363//a>static void /a href="+code=__exit" class="sref">__exit//a> /a href="+code=raw_exit" class="sref">raw_exit//a>(void)1<364 a.{1<365//a> /a href="+code=device_destroy" class="sref">device_destroy//a>(/a href="+code=raw_class" class="sref">raw_class//a>, /a href="+code=MKDEV" class="sref">MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, 0));1<366//a> /a href="+code=class_destroy" class="sref">class_destroy//a>(/a href="+code=raw_class" class="sref">raw_class//a>);1<367//a> /a href="+code=cdev_del" class="sref">cdev_del//a>(&/a href="+code=raw_cdev" class="sref">raw_cdev//a>);1<368//a> /a href="+code=unregister_chrdev_region" class="sref">unregister_chrdev_region//a>(/a href="+code=MKDEV" class="sref">MKDEV//a>(/a href="+code=RAW_MAJOR" class="sref">RAW_MAJOR//a>, 0), /a href="+code=max_raw_minors" class="sref">max_raw_minors//a>);1<369//a>}1<370//a>1<371//a>/a href="+code=module_init" class="sref">module_init//a>(/a href="+code=raw_init" class="sref">raw_init//a>);1<372 a./a href="+code=module_exit" class="sref">module_exit//a>(/a href="+code=raw_exit" class="sref">raw_exit//a>);1<373//a>/a href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE//a>(/spa3 class="string">"GPL"//spa3.);1<374//a>
lxr.linux.no kindly hosted by Redpill Linpro AS//a>, provider of Linux consulting and operations services since<1995.