这句:
addr = (volatile unsigned int *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * minor);
还有这句:
addr[GPIO_SET_OFFSET] = 1 << arg;
int gpio_ioctl(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)
{
volatile unsigned int * addr;
int minor = MINOR(inode->i_rdev);
int err = -1;
// printk(KERN_ALERT "ioctl called\n");
if(minor > MAX_PORTS)
return -ENODEV;
//check magicnum
if(_IOC_TYPE(cmd) != MAGIC_NUM)
return -ENOTTY;
if(_IOC_NR(cmd) > MAX_CMDS)
return -ENOTTY;
/*
check read or write cmd,if 1 ,check the user buf
*/
if(_IOC_DIR(cmd) & _IOC_READ){
err = !access_ok(VERIFY_READ,(void __user*)arg,_IOC_SIZE(cmd));
if(err) return -EFAULT;
}
else if(_IOC_DIR(cmd) & _IOC_WRITE){
err = !access_ok(VERIFY_WRITE,(void __user*)arg,_IOC_SIZE(cmd));
if(err) return -EFAULT;
}
addr = (volatile unsigned int *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * minor);
switch(cmd){
case GPIO_SET_PIN:
if(arg < 32)
addr[GPIO_SET_OFFSET] = 1 << arg;
break;
case GPIO_CLR_PIN:
if(arg < 32)
addr[GPIO_CLR_OFFSET] = 1 << arg;
break;
case GPIO_SET_PINS:
addr[GPIO_SET_OFFSET] = arg;
break;
case GPIO_CLR_PINS:
addr[GPIO_CLR_OFFSET] = arg;
break;
case GPIO_DIR_IN:
if(arg < 32)
addr[GPIO_DIR_OFFSET] &= ~(1 << arg);
break;
case GPIO_DIR_OUT:
if(arg < 32)
addr[GPIO_DIR_OFFSET] |= 1 << arg;
break;
case GPIO_READ_PIN:
break;
case GPIO_READ_PINS:
break;
case GPIO_WRITE_PIN:
break;
case GPIO_WRITE_PINS:
break;
}
return 0;
} |