static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up) { if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format))) return -EFAULT; return 0; }
static int mtd_read(struct inode *inode,struct file *file, char *buf, int count) #endif { struct mtd_info *mtd = (struct mtd_info *)file->private_data; size_t retlen=0; size_t total_retlen=0; int ret=0; #ifndef NO_MM int len; char *kbuf; #endif DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); if (FILE_POS + count > mtd->size) count = mtd->size - FILE_POS; if (!count) return 0; /* FIXME: Use kiovec in 2.3 or 2.2+rawio, or at * least split the IO into smaller chunks. */ #ifdef NO_MM ret = MTD_READ(mtd, FILE_POS, count, &retlen, buf); if (!ret) { FILE_POS += retlen; ret = retlen; } total_retlen = ret; #else while (count) { if (count > MAX_KMALLOC_SIZE) len = MAX_KMALLOC_SIZE; else len = count; kbuf=kmalloc(len,GFP_KERNEL); if (!kbuf) return -ENOMEM; ret = MTD_READ(mtd, FILE_POS, len, &retlen, kbuf); if (!ret) { FILE_POS += retlen; if (copy_to_user(buf, kbuf, retlen)) { kfree(kbuf); return -EFAULT; } else total_retlen += retlen; count -= retlen; buf += retlen; } else { kfree(kbuf); return ret; } kfree(kbuf); } #endif return total_retlen; } /* mtd_read */
int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) { int uninitialized_var(err); struct net *net = sock_net(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct in6_flowlabel_req freq; struct ipv6_fl_socklist *sfl1 = NULL; struct ipv6_fl_socklist *sfl; struct ipv6_fl_socklist __rcu **sflp; struct ip6_flowlabel *fl, *fl1 = NULL; if (optlen < sizeof(freq)) return -EINVAL; if (copy_from_user(&freq, optval, sizeof(freq))) return -EFAULT; switch (freq.flr_action) { case IPV6_FL_A_PUT: if (freq.flr_flags & IPV6_FL_F_REFLECT) { if (sk->sk_protocol != IPPROTO_TCP) return -ENOPROTOOPT; if (!np->repflow) return -ESRCH; np->flow_label = 0; np->repflow = 0; return 0; } spin_lock_bh(&ip6_sk_fl_lock); for (sflp = &np->ipv6_fl_list; (sfl = rcu_dereference_protected(*sflp, lockdep_is_held(&ip6_sk_fl_lock))) != NULL; sflp = &sfl->next) { if (sfl->fl->label == freq.flr_label) { if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK)) np->flow_label &= ~IPV6_FLOWLABEL_MASK; *sflp = sfl->next; spin_unlock_bh(&ip6_sk_fl_lock); fl_release(sfl->fl); kfree_rcu(sfl, rcu); return 0; } } spin_unlock_bh(&ip6_sk_fl_lock); return -ESRCH; case IPV6_FL_A_RENEW: rcu_read_lock_bh(); for_each_sk_fl_rcu(np, sfl) { if (sfl->fl->label == freq.flr_label) { err = fl6_renew(sfl->fl, freq.flr_linger, freq.flr_expires); rcu_read_unlock_bh(); return err; } } rcu_read_unlock_bh(); if (freq.flr_share == IPV6_FL_S_NONE && ns_capable(net->user_ns, CAP_NET_ADMIN)) { fl = fl_lookup(net, freq.flr_label); if (fl) { err = fl6_renew(fl, freq.flr_linger, freq.flr_expires); fl_release(fl); return err; } } return -ESRCH; case IPV6_FL_A_GET: if (freq.flr_flags & IPV6_FL_F_REFLECT) { struct net *net = sock_net(sk); if (net->ipv6.sysctl.flowlabel_consistency) { net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n"); return -EPERM; } if (sk->sk_protocol != IPPROTO_TCP) return -ENOPROTOOPT; np->repflow = 1; return 0; } if (freq.flr_label & ~IPV6_FLOWLABEL_MASK) return -EINVAL; if (net->ipv6.sysctl.flowlabel_state_ranges && (freq.flr_label & IPV6_FLOWLABEL_STATELESS_FLAG)) return -ERANGE; fl = fl_create(net, sk, &freq, optval, optlen, &err); if (!fl) return err; sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL); if (freq.flr_label) { err = -EEXIST; rcu_read_lock_bh(); for_each_sk_fl_rcu(np, sfl) { if (sfl->fl->label == freq.flr_label) { if (freq.flr_flags&IPV6_FL_F_EXCL) { rcu_read_unlock_bh(); goto done; } fl1 = sfl->fl; atomic_inc(&fl1->users); break; } } rcu_read_unlock_bh(); if (!fl1) fl1 = fl_lookup(net, freq.flr_label); if (fl1) { recheck: err = -EEXIST; if (freq.flr_flags&IPV6_FL_F_EXCL) goto release; err = -EPERM; if (fl1->share == IPV6_FL_S_EXCL || fl1->share != fl->share || ((fl1->share == IPV6_FL_S_PROCESS) && (fl1->owner.pid == fl->owner.pid)) || ((fl1->share == IPV6_FL_S_USER) && uid_eq(fl1->owner.uid, fl->owner.uid))) goto release; err = -ENOMEM; if (!sfl1) goto release; if (fl->linger > fl1->linger) fl1->linger = fl->linger; if ((long)(fl->expires - fl1->expires) > 0) fl1->expires = fl->expires; fl_link(np, sfl1, fl1); fl_free(fl); return 0; release: fl_release(fl1); goto done; } } err = -ENOENT; if (!(freq.flr_flags&IPV6_FL_F_CREATE)) goto done; err = -ENOMEM; if (!sfl1) goto done; err = mem_check(sk); if (err != 0) goto done; fl1 = fl_intern(net, fl, freq.flr_label); if (fl1) goto recheck; if (!freq.flr_label) { if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, &fl->label, sizeof(fl->label))) { /* Intentionally ignore fault. */ } } fl_link(np, sfl1, fl); return 0; default: return -EINVAL; }
static long jpeg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret; struct jpeg_control *ctrl; ctrl = (struct jpeg_control *)file->private_data; if (!ctrl) { jpeg_err("jpeg invalid input argument\n"); return -1; } switch (cmd) { case IOCTL_JPEG_DEC_EXE: ret = copy_from_user(&ctrl->dec_param, (struct jpeg_dec_param *)arg, sizeof(struct jpeg_dec_param)); jpeg_exe_dec(ctrl); ret = copy_to_user((void *)arg, (void *) &ctrl->dec_param, sizeof(struct jpeg_dec_param)); break; case IOCTL_JPEG_ENC_EXE: ret = copy_from_user(&ctrl->enc_param, (struct jpeg_enc_param *)arg, sizeof(struct jpeg_enc_param)); jpeg_exe_enc(ctrl); ret = copy_to_user((void *)arg, (void *) &ctrl->enc_param, sizeof(struct jpeg_enc_param)); break; case IOCTL_GET_DEC_IN_BUF: case IOCTL_GET_ENC_OUT_BUF: return jpeg_get_stream_buf(arg); case IOCTL_GET_DEC_OUT_BUF: case IOCTL_GET_ENC_IN_BUF: return jpeg_get_frame_buf(arg); case IOCTL_GET_PHYADDR: return jpeg_ctrl->mem.frame_data_addr; case IOCTL_GET_PHYMEM_BASE: #ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG if (copy_to_user((void *)arg, &jpeg_ctrl->mem.base, sizeof(unsigned int))) { jpeg_err("IOCTL_GET_PHYMEM_BASE:::copy_to_user error\n"); return -1; } return 0; #else return -1; #endif case IOCTL_GET_PHYMEM_SIZE: #ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG ret = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * 1024; if (copy_to_user((void *)arg, &ret, sizeof(unsigned int))) { jpeg_err("IOCTL_GET_PHYMEM_SIZE:::copy_to_user error\n"); return -1; } return 0; #else return -1; #endif case IOCTL_SET_DEC_PARAM: ret = copy_from_user(&ctrl->dec_param, (struct jpeg_dec_param *)arg, sizeof(struct jpeg_dec_param)); ret = jpeg_set_dec_param(ctrl); break; case IOCTL_SET_ENC_PARAM: ret = copy_from_user(&ctrl->enc_param, (struct jpeg_enc_param *)arg, sizeof(struct jpeg_enc_param)); ret = jpeg_set_enc_param(ctrl); break; default: break; } return 0; }
static int ecs_ctrl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *pa = (void __user *)arg; short flag; short delay; int parms[4]; int ypr[12]; switch (cmd) { case ECOMPASS_IOC_SET_MODE: break; case ECOMPASS_IOC_SET_DELAY: if (copy_from_user(&delay, pa, sizeof(delay))) return -EFAULT; ecompass_delay = delay; break; case ECOMPASS_IOC_GET_DELAY: delay = ecompass_delay; if (copy_to_user(pa, &delay, sizeof(delay))) return -EFAULT; break; case ECOMPASS_IOC_SET_AFLAG: if (copy_from_user(&flag, pa, sizeof(flag))) return -EFAULT; if (flag < 0 || flag > 1) return -EINVAL; atomic_set(&a_flag, flag); break; case ECOMPASS_IOC_GET_AFLAG: flag = atomic_read(&a_flag); if (copy_to_user(pa, &flag, sizeof(flag))) return -EFAULT; break; case ECOMPASS_IOC_SET_MFLAG: if (copy_from_user(&flag, pa, sizeof(flag))) return -EFAULT; if (flag < 0 || flag > 1) return -EINVAL; atomic_set(&m_flag, flag); break; case ECOMPASS_IOC_GET_MFLAG: flag = atomic_read(&m_flag); if (copy_to_user(pa, &flag, sizeof(flag))) return -EFAULT; break; case ECOMPASS_IOC_SET_OFLAG: if (copy_from_user(&flag, pa, sizeof(flag))) return -EFAULT; if (flag < 0 || flag > 1) return -EINVAL; atomic_set(&o_flag, flag); break; case ECOMPASS_IOC_GET_OFLAG: flag = atomic_read(&o_flag); if (copy_to_user(pa, &flag, sizeof(flag))) return -EFAULT; break; case ECOMPASS_IOC_SET_APARMS: if (copy_from_user(parms, pa, sizeof(parms))) return -EFAULT; /* acceleration x-axis */ input_set_abs_params(ecs_data_device, ABS_X, parms[0], parms[1], parms[2], parms[3]); /* acceleration y-axis */ input_set_abs_params(ecs_data_device, ABS_Y, parms[0], parms[1], parms[2], parms[3]); /* acceleration z-axis */ input_set_abs_params(ecs_data_device, ABS_Z, parms[0], parms[1], parms[2], parms[3]); break; case ECOMPASS_IOC_GET_APARMS: break; case ECOMPASS_IOC_SET_MPARMS: if (copy_from_user(parms, pa, sizeof(parms))) return -EFAULT; /* magnetic raw x-axis */ input_set_abs_params(ecs_data_device, ABS_HAT0X, parms[0], parms[1], parms[2], parms[3]); /* magnetic raw y-axis */ input_set_abs_params(ecs_data_device, ABS_HAT0Y, parms[0], parms[1], parms[2], parms[3]); /* magnetic raw z-axis */ input_set_abs_params(ecs_data_device, ABS_BRAKE, parms[0], parms[1], parms[2], parms[3]); break; case ECOMPASS_IOC_GET_MPARMS: break; case ECOMPASS_IOC_SET_OPARMS_YAW: if (copy_from_user(parms, pa, sizeof(parms))) return -EFAULT; /* orientation yaw */ input_set_abs_params(ecs_data_device, ABS_RX, parms[0], parms[1], parms[2], parms[3]); break; case ECOMPASS_IOC_GET_OPARMS_YAW: break; case ECOMPASS_IOC_SET_OPARMS_PITCH: if (copy_from_user(parms, pa, sizeof(parms))) return -EFAULT; /* orientation pitch */ input_set_abs_params(ecs_data_device, ABS_RY, parms[0], parms[1], parms[2], parms[3]); break; case ECOMPASS_IOC_GET_OPARMS_PITCH: break; case ECOMPASS_IOC_SET_OPARMS_ROLL: if (copy_from_user(parms, pa, sizeof(parms))) return -EFAULT; /* orientation roll */ input_set_abs_params(ecs_data_device, ABS_RZ, parms[0], parms[1], parms[2], parms[3]); break; case ECOMPASS_IOC_GET_OPARMS_ROLL: break; case ECOMPASS_IOC_SET_YPR: if (copy_from_user(ypr, pa, sizeof(ypr))) return -EFAULT; /* Report acceleration sensor information */ if (atomic_read(&a_flag)) { input_report_abs(ecs_data_device, ABS_X, ypr[0]); input_report_abs(ecs_data_device, ABS_Y, ypr[1]); input_report_abs(ecs_data_device, ABS_Z, ypr[2]); input_report_abs(ecs_data_device, ABS_WHEEL, ypr[3]); } /* Report magnetic sensor information */ if (atomic_read(&m_flag)) { input_report_abs(ecs_data_device, ABS_HAT0X, ypr[4]); input_report_abs(ecs_data_device, ABS_HAT0Y, ypr[5]); input_report_abs(ecs_data_device, ABS_BRAKE, ypr[6]); input_report_abs(ecs_data_device, ABS_GAS, ypr[7]); } /* Report orientation information */ if (atomic_read(&o_flag)) { input_report_abs(ecs_data_device, ABS_RX, ypr[8]); input_report_abs(ecs_data_device, ABS_RY, ypr[9]); input_report_abs(ecs_data_device, ABS_RZ, ypr[10]); input_report_abs(ecs_data_device, ABS_RUDDER, ypr[11]); } input_sync(ecs_data_device); break; default: break; } return 0; }
/** * iowarrior_ioctl */ static long iowarrior_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct iowarrior *dev = NULL; __u8 *buffer; __u8 __user *user_buffer; int retval; int io_res; /* checks for bytes read/written and copy_to/from_user results */ dev = file->private_data; if (dev == NULL) { return -ENODEV; } buffer = kzalloc(dev->report_size, GFP_KERNEL); if (!buffer) return -ENOMEM; /* lock this object */ mutex_lock(&iowarrior_mutex); mutex_lock(&dev->mutex); /* verify that the device wasn't unplugged */ if (!dev->present) { retval = -ENODEV; goto error_out; } dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd, arg); retval = 0; io_res = 0; switch (cmd) { case IOW_WRITE: if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 || dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 || dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 || dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) { user_buffer = (__u8 __user *)arg; io_res = copy_from_user(buffer, user_buffer, dev->report_size); if (io_res) { retval = -EFAULT; } else { io_res = usb_set_report(dev->interface, 2, 0, buffer, dev->report_size); if (io_res < 0) retval = io_res; } } else { retval = -EINVAL; dev_err(&dev->interface->dev, "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n", dev->product_id); } break; case IOW_READ: user_buffer = (__u8 __user *)arg; io_res = usb_get_report(dev->udev, dev->interface->cur_altsetting, 1, 0, buffer, dev->report_size); if (io_res < 0) retval = io_res; else { io_res = copy_to_user(user_buffer, buffer, dev->report_size); if (io_res < 0) retval = -EFAULT; } break; case IOW_GETINFO: { /* Report available information for the device */ struct iowarrior_info info; /* needed for power consumption */ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc; memset(&info, 0, sizeof(info)); /* directly from the descriptor */ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); info.product = dev->product_id; info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice); /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */ info.speed = le16_to_cpu(dev->udev->speed); info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber; info.report_size = dev->report_size; /* serial number string has been read earlier 8 chars or empty string */ memcpy(info.serial, dev->chip_serial, sizeof(dev->chip_serial)); if (cfg_descriptor == NULL) { info.power = -1; /* no information available */ } else { /* the MaxPower is stored in units of 2mA to make it fit into a byte-value */ info.power = cfg_descriptor->bMaxPower * 2; } io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, sizeof(struct iowarrior_info)); if (io_res < 0) retval = -EFAULT; break; } default: /* return that we did not understand this ioctl call */ retval = -ENOTTY; break; } error_out: /* unlock the device */ mutex_unlock(&dev->mutex); mutex_unlock(&iowarrior_mutex); kfree(buffer); return retval; }
static int wpa_get_scan(PSDevice pDevice, struct viawget_wpa_param *param) { struct viawget_scan_result *scan_buf; PSMgmtObject pMgmt = pDevice->pMgmt; PWLAN_IE_SSID pItemSSID; PKnownBSS pBSS; unsigned char *pBuf; int ret = 0; u16 count = 0; u16 ii, jj; #if 1 unsigned char *ptempBSS; ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC); if (ptempBSS == NULL) { printk("bubble sort kmalloc memory fail@@@\n"); ret = -ENOMEM; return ret; } for (ii = 0; ii < MAX_BSS_NUM; ii++) { for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) { if((pMgmt->sBSSList[jj].bActive!=true) || ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) { memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS)); memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS)); memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS)); } } } kfree(ptempBSS); // printk("bubble sort result:\n"); //for (ii = 0; ii < MAX_BSS_NUM; ii++) // printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID, // pMgmt->sBSSList[ii].uRSSI); #endif //******mike:bubble sort by stronger RSSI*****// count = 0; pBSS = &(pMgmt->sBSSList[0]); for (ii = 0; ii < MAX_BSS_NUM; ii++) { pBSS = &(pMgmt->sBSSList[ii]); if (!pBSS->bActive) continue; count++; } pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); if (pBuf == NULL) { ret = -ENOMEM; return ret; } scan_buf = (struct viawget_scan_result *)pBuf; pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) { pBSS = &(pMgmt->sBSSList[ii]); if (pBSS->bActive) { if (jj >= count) break; memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); scan_buf->ssid_len = pItemSSID->len; scan_buf->freq = frequency_list[pBSS->uChannel-1]; scan_buf->caps = pBSS->wCapInfo; //scan_buf->caps = pBSS->wCapInfo; //scan_buf->qual = //scan_buf->noise = //scan_buf->level = //scan_buf->maxrate = if (pBSS->wWPALen != 0) { scan_buf->wpa_ie_len = pBSS->wWPALen; memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); } if (pBSS->wRSNLen != 0) { scan_buf->rsn_ie_len = pBSS->wRSNLen; memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); } scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result)); jj ++; } } if (jj < count) count = jj; if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) { ret = -EFAULT; } param->u.scan_results.scan_count = count; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count) kfree(pBuf); return ret; }
static ssize_t printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) { struct printer_dev *dev = fd->private_data; unsigned long flags; size_t size; size_t bytes_copied; struct usb_request *req; /* This is a pointer to the current USB rx request. */ struct usb_request *current_rx_req; /* This is the number of bytes in the current rx buffer. */ size_t current_rx_bytes; /* This is a pointer to the current rx buffer. */ u8 *current_rx_buf; if (len == 0) return -EINVAL; DBG(dev, "printer_read trying to read %d bytes\n", (int)len); spin_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); /* We will use this flag later to check if a printer reset happened * after we turn interrupts back on. */ dev->reset_printer = 0; setup_rx_reqs(dev); bytes_copied = 0; current_rx_req = dev->current_rx_req; current_rx_bytes = dev->current_rx_bytes; current_rx_buf = dev->current_rx_buf; dev->current_rx_req = NULL; dev->current_rx_bytes = 0; dev->current_rx_buf = NULL; /* Check if there is any data in the read buffers. Please note that * current_rx_bytes is the number of bytes in the current rx buffer. * If it is zero then check if there are any other rx_buffers that * are on the completed list. We are only out of data if all rx * buffers are empty. */ if ((current_rx_bytes == 0) && (likely(list_empty(&dev->rx_buffers)))) { /* Turn interrupts back on before sleeping. */ spin_unlock_irqrestore(&dev->lock, flags); /* * If no data is available check if this is a NON-Blocking * call or not. */ if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { spin_unlock(&dev->lock_printer_io); return -EAGAIN; } /* Sleep until data is available */ wait_event_interruptible(dev->rx_wait, (likely(!list_empty(&dev->rx_buffers)))); spin_lock_irqsave(&dev->lock, flags); } /* We have data to return then copy it to the caller's buffer.*/ while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) && len) { if (current_rx_bytes == 0) { req = container_of(dev->rx_buffers.next, struct usb_request, list); list_del_init(&req->list); if (req->actual && req->buf) { current_rx_req = req; current_rx_bytes = req->actual; current_rx_buf = req->buf; } else { list_add(&req->list, &dev->rx_reqs); continue; } } /* Don't leave irqs off while doing memory copies */ spin_unlock_irqrestore(&dev->lock, flags); if (len > current_rx_bytes) size = current_rx_bytes; else size = len; size -= copy_to_user(buf, current_rx_buf, size); bytes_copied += size; len -= size; buf += size; spin_lock_irqsave(&dev->lock, flags); /* We've disconnected or reset so return. */ if (dev->reset_printer) { list_add(¤t_rx_req->list, &dev->rx_reqs); spin_unlock_irqrestore(&dev->lock, flags); spin_unlock(&dev->lock_printer_io); return -EAGAIN; } /* If we not returning all the data left in this RX request * buffer then adjust the amount of data left in the buffer. * Othewise if we are done with this RX request buffer then * requeue it to get any incoming data from the USB host. */ if (size < current_rx_bytes) { current_rx_bytes -= size; current_rx_buf += size; } else { list_add(¤t_rx_req->list, &dev->rx_reqs); current_rx_bytes = 0; current_rx_buf = NULL; current_rx_req = NULL; } }
int libcfs_ioctl_popdata(void *arg, void *data, int size) { if (copy_to_user((char *)arg, data, size)) return -EFAULT; return 0; }
asmlinkage int ppc_rtas(struct rtas_args __user *uargs) { struct rtas_args args; unsigned long flags; char *buff_copy, *errbuf = NULL; int nargs; int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0) return -EFAULT; nargs = args.nargs; if (nargs > ARRAY_SIZE(args.args) || args.nret > ARRAY_SIZE(args.args) || nargs + args.nret > ARRAY_SIZE(args.args)) return -EINVAL; /* Copy in args. */ if (copy_from_user(args.args, uargs->args, nargs * sizeof(rtas_arg_t)) != 0) return -EFAULT; if (args.token == RTAS_UNKNOWN_SERVICE) return -EINVAL; args.rets = &args.args[nargs]; memset(args.rets, 0, args.nret * sizeof(rtas_arg_t)); /* Need to handle ibm,suspend_me call specially */ if (args.token == ibm_suspend_me_token) { rc = rtas_ibm_suspend_me(&args); if (rc) return rc; goto copy_return; } buff_copy = get_errorlog_buffer(); flags = lock_rtas(); rtas.args = args; enter_rtas(__pa(&rtas.args)); args = rtas.args; /* A -1 return code indicates that the last command couldn't be completed due to a hardware error. */ if (args.rets[0] == -1) errbuf = __fetch_rtas_last_error(buff_copy); unlock_rtas(flags); if (buff_copy) { if (errbuf) log_error(errbuf, ERR_TYPE_RTAS_LOG, 0); kfree(buff_copy); } copy_return: /* Copy out args. */ if (copy_to_user(uargs->args + nargs, args.args + nargs, args.nret * sizeof(rtas_arg_t)) != 0) return -EFAULT; return 0; }
static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING, .firmware_version = 1, .identity = "MPC83xx", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: mpc83xx_wdt_keepalive(); return 0; case WDIOC_GETTIMEOUT: return put_user(timeout_sec, p); default: return -ENOTTY; } } static const struct file_operations mpc83xx_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = mpc83xx_wdt_write, .ioctl = mpc83xx_wdt_ioctl, .open = mpc83xx_wdt_open, .release = mpc83xx_wdt_release, }; static struct miscdevice mpc83xx_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mpc83xx_wdt_fops, }; static int __devinit mpc83xx_wdt_probe(struct platform_device *dev) { struct resource *r; int ret; unsigned int *freq = dev->dev.platform_data; /* get a pointer to the register memory */ r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) { ret = -ENODEV; goto err_out; } wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt)); if (wd_base == NULL) { ret = -ENOMEM; goto err_out; } ret = misc_register(&mpc83xx_wdt_miscdev); if (ret) { printk(KERN_ERR "cannot register miscdev on minor=%d " "(err=%d)\n", WATCHDOG_MINOR, ret); goto err_unmap; } /* Calculate the timeout in seconds */ if (prescale) timeout_sec = (timeout * 0x10000) / (*freq); else timeout_sec = timeout / (*freq); printk(KERN_INFO "WDT driver for MPC83xx initialized. " "mode:%s timeout=%d (%d seconds)\n", reset ? "reset":"interrupt", timeout, timeout_sec); spin_lock_init(&wdt_spinlock); return 0; err_unmap: iounmap(wd_base); err_out: return ret; } static int __devexit mpc83xx_wdt_remove(struct platform_device *dev) { misc_deregister(&mpc83xx_wdt_miscdev); iounmap(wd_base); return 0; } static struct platform_driver mpc83xx_wdt_driver = { .probe = mpc83xx_wdt_probe, .remove = __devexit_p(mpc83xx_wdt_remove), .driver = { .name = "mpc83xx_wdt", }, }; static int __init mpc83xx_wdt_init(void) { return platform_driver_register(&mpc83xx_wdt_driver); } static void __exit mpc83xx_wdt_exit(void) { platform_driver_unregister(&mpc83xx_wdt_driver); }
/******************************** the module driver ************************************************************/ static int sep0611_overlay_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { unsigned int intArg,data; overlay_config_t config; lcdc_timming timming_tmp; switch(cmd) { #if 0 case OVERLAY_FORBID: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; overlay_forbid = intArg; return 0; #endif #if USE_PICTURE case 111://GET_IMG //if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) // return -EFAULT; return sep0611_overlay_get_img(); #endif case OVERLAY_PRINT_REGS: dprintk("print regs:\n"); for(intArg=0; intArg<=0xCC;intArg+=4) { printk("reg[0x%x] = (0x%x)\n", (unsigned int)io + intArg, readl(io + intArg)); } break; case OVERLAY_GET_STARTBUF: dprintk("overlay_kernel ioctl get startbuffer!\n"); if(copy_to_user((unsigned int *)arg, &over1_addr_phy, sizeof(unsigned int))) { dprintk("error while copy!\n"); return -EFAULT; }else{ // dprintk("success get startbuf: 0x%x",over1_addr_phy); } break; case OVERLAY_AUTORP_CTL: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; if(intArg == 1){ writel(0, io + SEP0611_ACSR); data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<13); data |=(0x2<<13); writel(data, io + SEP0611_LCDCBCR); mdelay(10); writel(1, io + SEP0611_ACSR); dprintk("ctl enable auto repair\n"); }else{ data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<13); writel(data, io + SEP0611_LCDCBCR); dprintk("ctl disable auto repair\n"); } break; case OVERLAY_SHOW_CURSOR: return sep0611_overlay_drawcursor(); case OVERLAY_SETPOS_CURSOR: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; return sep0611_overlay_setpos_cursor(intArg); case OVERLAY_LAYERS_CTL://enable or disable layers if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; sep0611_overlay_layers_ctl(intArg); break; case 114://set lcdc timming if(copy_from_user(&timming_tmp, (lcdc_timming *)arg, sizeof(lcdc_timming))) return -EFAULT; sep0611_overlay_settimming(timming_tmp); break; case 115://set lcdc base layer size and format if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; intArg = 0; dprintk("set base size:(%d,%d)\n", config.width, config.height); intArg = XMAX(config.width)|YMAX(config.height); writel(intArg, io + SEP0611_BBPCR); writel(config.width, io + SEP0611_BASE_RAW_IMAGE_WIDTH); switch(config.format) { case V4L2_PIX_FMT_RGB565: dprintk("use rgb565\n"); data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<27); writel(data, io + SEP0611_LCDCBCR); break; case V4L2_PIX_FMT_RGB24: dprintk("use rgb888\n"); data = readl(io + SEP0611_LCDCBCR); data &= ~(0x3<<27); data |= (0x2<<27); writel(data, io + SEP0611_LCDCBCR); break; default: dprintk("not support!\n"); break; } break; case OVERLAY_GET_POSITION: return sep0611_overlay_get_pos((overlay_config_t*)arg); case OVERLAY_GET_SCREEN_INFO: return sep0611_overlay_get_screenInfo((overlay_config_t*)arg); case OVERLAY_SET_POSITION: if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; return sep0611_overlay_set_pos(config); case OVERLAY_QUEUE_BUFFER: if(copy_from_user(&intArg, (overlay_config_t *)arg, sizeof(unsigned int))) return -EFAULT; return sep0611_overlay_q_buffer((unsigned int)intArg); case OVERLAY_SET_CONFIGURE: if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; sep0611_overlay_set_configure(config); //sep0611_overlay_q_buffer(over1_addr_phy); break; case OVERLAY_SET_DISABLE: return sep0611_overlay_disable(); case OVERLAY_SET_ENABLE: return sep0611_overlay_enable(); case OVERLAY_COMMON_ENABLE: sep0611_common_enable(); return 0; case OVERLAY_COMMON_DISABLE: sep0611_common_disable(); return 0; case OVERLAY_SWITCHTO_VIDEO: sep0611_switchto_mode(0); break; case OVERLAY_SWITCHTO_HDMI: sep0611_switchto_mode(1); break; case OVERLAY_SWITCHTO_LCD: sep0611_switchto_mode(2); break; default: dprintk(" Unsupported IOCTL(%d)!!!\n", cmd); break; } return 0; }
static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up) { if (copy_to_user(up, kp, sizeof(struct v4l2_input32))) return -EFAULT; return 0; }
static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) { struct v4l2_plane32 __user *uplane32; struct v4l2_plane __user *uplane; compat_caddr_t p; int num_planes; int ret; if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) || put_user(kp->index, &up->index) || put_user(kp->type, &up->type) || put_user(kp->flags, &up->flags) || put_user(kp->memory, &up->memory) || put_user(kp->input, &up->input)) return -EFAULT; if (put_user(kp->bytesused, &up->bytesused) || put_user(kp->field, &up->field) || put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) || copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) || put_user(kp->sequence, &up->sequence) || put_user(kp->reserved, &up->reserved)) return -EFAULT; if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) { num_planes = kp->length; if (num_planes == 0) return 0; uplane = kp->m.planes; if (get_user(p, &up->m.planes)) return -EFAULT; uplane32 = compat_ptr(p); while (--num_planes >= 0) { ret = put_v4l2_plane32(uplane, uplane32, kp->memory); if (ret) return ret; ++uplane; ++uplane32; } } else { switch (kp->memory) { case V4L2_MEMORY_MMAP: if (put_user(kp->length, &up->length) || put_user(kp->m.offset, &up->m.offset)) return -EFAULT; break; case V4L2_MEMORY_USERPTR: if (put_user(kp->length, &up->length) || put_user(kp->m.userptr, &up->m.userptr)) return -EFAULT; break; case V4L2_MEMORY_OVERLAY: if (put_user(kp->m.offset, &up->m.offset)) return -EFAULT; break; } } return 0; }
static long epx_c3_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int options, retval = -EINVAL; int __user *argp = (void __user *)arg; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING, .firmware_version = 0, .identity = "Winsystems EPX-C3 H/W Watchdog", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, argp); case WDIOC_SETOPTIONS: if (get_user(options, argp)) return -EFAULT; if (options & WDIOS_DISABLECARD) { epx_c3_stop(); retval = 0; } if (options & WDIOS_ENABLECARD) { epx_c3_start(); retval = 0; } return retval; case WDIOC_KEEPALIVE: epx_c3_pet(); return 0; case WDIOC_GETTIMEOUT: return put_user(WATCHDOG_TIMEOUT, argp); default: return -ENOTTY; } } static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) epx_c3_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static const struct file_operations epx_c3_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = epx_c3_write, .unlocked_ioctl = epx_c3_ioctl, .open = epx_c3_open, .release = epx_c3_release, }; static struct miscdevice epx_c3_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &epx_c3_fops, }; static struct notifier_block epx_c3_notifier = { .notifier_call = epx_c3_notify_sys, }; static const char banner[] __initdata = KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n"; static int __init watchdog_init(void) { int ret; if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog")) return -EBUSY; ret = register_reboot_notifier(&epx_c3_notifier); if (ret) { // printk(KERN_ERR PFX "cannot register reboot notifier " ; goto out; } ret = misc_register(&epx_c3_miscdev); if (ret) { // printk(KERN_ERR PFX "cannot register miscdev on minor=%d " ; unregister_reboot_notifier(&epx_c3_notifier); goto out; } ; return 0; out: release_region(EPXC3_WATCHDOG_CTL_REG, 2); return ret; } static void __exit watchdog_exit(void) { misc_deregister(&epx_c3_miscdev); unregister_reboot_notifier(&epx_c3_notifier); release_region(EPXC3_WATCHDOG_CTL_REG, 2); }
ssize_t ar7240_i2s_read(struct file * filp, char __user * buf,size_t count, loff_t * f_pos)//gl-inet { #define prev_tail(t) ({ (t == 0) ? (NUM_DESC - 1) : (t - 1); }) #define next_tail(t) ({ (t == (NUM_DESC - 1)) ? 0 : (t + 1); }) uint8_t *data; //ssize_t retval; unsigned long retval; struct ar7240_i2s_softc *sc = &sc_buf_var; i2s_dma_buf_t *dmabuf = &sc->sc_rbuf; i2s_buf_t *scbuf; ar7240_mbox_dma_desc *desc; unsigned int byte_cnt, mode = 1, offset = 0, tail = dmabuf->tail; unsigned long desc_p; int need_start = 0; byte_cnt = count; if (sc->ropened < 2) { ar7240_reg_rmw_set(MBOX_INT_ENABLE, MBOX0_TX_DMA_COMPLETE); need_start = 1; } sc->ropened = 2; scbuf = dmabuf->db_buf; desc = dmabuf->db_desc; desc_p = (unsigned long) dmabuf->db_desc_p; data = scbuf[0].bf_vaddr; desc_p += tail * sizeof(ar7240_mbox_dma_desc); while (byte_cnt && !desc[tail].OWN) { if (byte_cnt >= I2S_BUF_SIZE) { desc[tail].length = I2S_BUF_SIZE; byte_cnt -= I2S_BUF_SIZE; } else { desc[tail].length = byte_cnt; byte_cnt = 0; } //ar7240_dma_cache_sync(scbuf[tail].bf_vaddr, desc[tail].length);//gl-inet dma_cache_sync(NULL, scbuf[tail].bf_vaddr, desc[tail].length, DMA_FROM_DEVICE);//gl-inet desc[tail].rsvd2 = 0;//gl-inet retval = copy_to_user((buf + offset), (scbuf[tail].bf_vaddr), I2S_BUF_SIZE); if (retval) return retval; desc[tail].BufPtr = (unsigned int) scbuf[tail].bf_paddr; desc[tail].OWN = 1; tail = next_tail(tail); offset += I2S_BUF_SIZE; } dmabuf->tail = tail; if (need_start) { ar7240_i2sound_dma_desc((unsigned long) desc_p, mode); if (filp) { ar7240_i2sound_dma_start(mode); } } else if (!sc->rpause) { ar7240_i2sound_dma_resume(mode); } return offset; }
static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { int error; struct cnxt_serial * info = (struct cnxt_serial *)tty->driver_data; int retval; if (serial_paranoia_check(info, tty->device, "rs_ioctl")) return -ENODEV; if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); if (!arg) send_break(info, HZ/4); /* 1/4 second */ return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); send_break(info, arg ? arg*(HZ/10) : HZ/4); return 0; case TIOCGSOFTCAR: error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long)); if (error) return error; put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); return 0; case TIOCSSOFTCAR: get_user(arg, (unsigned long *) arg); tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); return 0; case TIOCGSERIAL: error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct)); if (error) return error; return get_serial_info(info, (struct serial_struct *) arg); case TIOCSSERIAL: return set_serial_info(info, (struct serial_struct *) arg); case TIOCSERGETLSR: /* Get line status register */ error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int)); if (error) return error; else return get_lsr_info(info, (unsigned int *) arg); case TIOCSERGSTRUCT: error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cnxt_serial)); if (error) return error; copy_to_user((struct cnxt_serial *) arg, info, sizeof(struct cnxt_serial)); return 0; default: return -ENOIOCTLCMD; } return 0; }
static int ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len) { struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 }; const struct ipv6_pinfo *inet6 = inet6_sk(sk); const struct inet_sock *inet = inet_sk(sk); const struct nf_conntrack_tuple_hash *h; struct sockaddr_in6 sin6; struct nf_conn *ct; __be32 flow_label; int bound_dev_if; lock_sock(sk); tuple.src.u3.in6 = sk->sk_v6_rcv_saddr; tuple.src.u.tcp.port = inet->inet_sport; tuple.dst.u3.in6 = sk->sk_v6_daddr; tuple.dst.u.tcp.port = inet->inet_dport; tuple.dst.protonum = sk->sk_protocol; bound_dev_if = sk->sk_bound_dev_if; flow_label = inet6->flow_label; release_sock(sk); if (tuple.dst.protonum != IPPROTO_TCP && tuple.dst.protonum != IPPROTO_SCTP) return -ENOPROTOOPT; if (*len < 0 || (unsigned int)*len < sizeof(sin6)) return -EINVAL; h = nf_conntrack_find_get(sock_net(sk), &nf_ct_zone_dflt, &tuple); if (!h) { pr_debug("IP6T_SO_ORIGINAL_DST: Can't find %pI6c/%u-%pI6c/%u.\n", &tuple.src.u3.ip6, ntohs(tuple.src.u.tcp.port), &tuple.dst.u3.ip6, ntohs(tuple.dst.u.tcp.port)); return -ENOENT; } ct = nf_ct_tuplehash_to_ctrack(h); sin6.sin6_family = AF_INET6; sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port; sin6.sin6_flowinfo = flow_label & IPV6_FLOWINFO_MASK; memcpy(&sin6.sin6_addr, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6, sizeof(sin6.sin6_addr)); nf_ct_put(ct); sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr, bound_dev_if); return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0; } static struct nf_sockopt_ops so_getorigdst6 = { .pf = NFPROTO_IPV6, .get_optmin = IP6T_SO_ORIGINAL_DST, .get_optmax = IP6T_SO_ORIGINAL_DST + 1, .get = ipv6_getorigdst, .owner = THIS_MODULE, }; static unsigned int ipv6_confirm(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { struct nf_conn *ct; enum ip_conntrack_info ctinfo; unsigned char pnum = ipv6_hdr(skb)->nexthdr; int protoff; __be16 frag_off; ct = nf_ct_get(skb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED_REPLY) goto out; protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum, &frag_off); if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { pr_debug("proto header not found\n"); goto out; } /* adjust seqs for loopback traffic only in outgoing direction */ if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && !nf_is_loopback_packet(skb)) { if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) { NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop); return NF_DROP; } } out: /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(skb); } static unsigned int ipv6_conntrack_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { return nf_conntrack_in(state->net, PF_INET6, state->hook, skb); } static unsigned int ipv6_conntrack_local(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { return nf_conntrack_in(state->net, PF_INET6, state->hook, skb); } static unsigned int ipv6_helper(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { struct nf_conn *ct; const struct nf_conn_help *help; const struct nf_conntrack_helper *helper; enum ip_conntrack_info ctinfo; __be16 frag_off; int protoff; u8 nexthdr; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(skb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED_REPLY) return NF_ACCEPT; help = nfct_help(ct); if (!help) return NF_ACCEPT; /* rcu_read_lock()ed by nf_hook_thresh */ helper = rcu_dereference(help->helper); if (!helper) return NF_ACCEPT; nexthdr = ipv6_hdr(skb)->nexthdr; protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, &frag_off); if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { pr_debug("proto header not found\n"); return NF_ACCEPT; } return helper->help(skb, protoff, ct, ctinfo); } static const struct nf_hook_ops ipv6_conntrack_ops[] = { { .hook = ipv6_conntrack_in, .pf = NFPROTO_IPV6, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP6_PRI_CONNTRACK, }, { .hook = ipv6_conntrack_local, .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_CONNTRACK, }, { .hook = ipv6_helper,
static long uinput_ioctl_handler(struct file *file, unsigned int cmd, unsigned long arg, void __user *p) { int retval; struct uinput_device *udev = file->private_data; struct uinput_ff_upload ff_up; struct uinput_ff_erase ff_erase; struct uinput_request *req; int length; char *phys; retval = mutex_lock_interruptible(&udev->mutex); if (retval) return retval; if (!udev->dev) { retval = uinput_allocate_device(udev); if (retval) goto out; } switch (cmd) { case UI_DEV_CREATE: retval = uinput_create_device(udev); break; case UI_DEV_DESTROY: uinput_destroy_device(udev); break; case UI_SET_EVBIT: retval = uinput_set_bit(arg, evbit, EV_MAX); break; case UI_SET_KEYBIT: retval = uinput_set_bit(arg, keybit, KEY_MAX); break; case UI_SET_RELBIT: retval = uinput_set_bit(arg, relbit, REL_MAX); break; case UI_SET_ABSBIT: retval = uinput_set_bit(arg, absbit, ABS_MAX); break; case UI_SET_MSCBIT: retval = uinput_set_bit(arg, mscbit, MSC_MAX); break; case UI_SET_LEDBIT: retval = uinput_set_bit(arg, ledbit, LED_MAX); break; case UI_SET_SNDBIT: retval = uinput_set_bit(arg, sndbit, SND_MAX); break; case UI_SET_FFBIT: retval = uinput_set_bit(arg, ffbit, FF_MAX); break; case UI_SET_SWBIT: retval = uinput_set_bit(arg, swbit, SW_MAX); break; case UI_SET_PROPBIT: retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); break; case UI_SET_PHYS: if (udev->state == UIST_CREATED) { retval = -EINVAL; goto out; } length = strnlen_user(p, 1024); if (length <= 0) { retval = -EFAULT; break; } kfree(udev->dev->phys); udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); if (!phys) { retval = -ENOMEM; break; } if (copy_from_user(phys, p, length)) { udev->dev->phys = NULL; kfree(phys); retval = -EFAULT; break; } phys[length - 1] = '\0'; break; case UI_BEGIN_FF_UPLOAD: retval = uinput_ff_upload_from_user(p, &ff_up); if (retval) break; req = uinput_request_find(udev, ff_up.request_id); if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) { retval = -EINVAL; break; } ff_up.retval = 0; ff_up.effect = *req->u.upload.effect; if (req->u.upload.old) ff_up.old = *req->u.upload.old; else memset(&ff_up.old, 0, sizeof(struct ff_effect)); retval = uinput_ff_upload_to_user(p, &ff_up); break; case UI_BEGIN_FF_ERASE: if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { retval = -EFAULT; break; } req = uinput_request_find(udev, ff_erase.request_id); if (!req || req->code != UI_FF_ERASE) { retval = -EINVAL; break; } ff_erase.retval = 0; ff_erase.effect_id = req->u.effect_id; if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) { retval = -EFAULT; break; } break; case UI_END_FF_UPLOAD: retval = uinput_ff_upload_from_user(p, &ff_up); if (retval) break; req = uinput_request_find(udev, ff_up.request_id); if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) { retval = -EINVAL; break; } req->retval = ff_up.retval; uinput_request_done(udev, req); break; case UI_END_FF_ERASE: if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { retval = -EFAULT; break; } req = uinput_request_find(udev, ff_erase.request_id); if (!req || req->code != UI_FF_ERASE) { retval = -EINVAL; break; } req->retval = ff_erase.retval; uinput_request_done(udev, req); break; default: retval = -EINVAL; } out: mutex_unlock(&udev->mutex); return retval; }
/** * mei_read - the read function. * * @file: pointer to file structure * @ubuf: pointer to user buffer * @length: buffer length * @offset: data offset in buffer * * Return: >=0 data length on success , <0 on error */ static ssize_t mei_read(struct file *file, char __user *ubuf, size_t length, loff_t *offset) { struct mei_cl *cl = file->private_data; struct mei_device *dev; struct mei_cl_cb *cb = NULL; int rets; int err; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; dev = cl->dev; mutex_lock(&dev->device_lock); if (dev->dev_state != MEI_DEV_ENABLED) { rets = -ENODEV; goto out; } if (length == 0) { rets = 0; goto out; } if (cl == &dev->iamthif_cl) { rets = mei_amthif_read(dev, file, ubuf, length, offset); goto out; } cb = mei_cl_read_cb(cl, file); if (cb) { /* read what left */ if (cb->buf_idx > *offset) goto copy_buffer; /* offset is beyond buf_idx we have no more data return 0 */ if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { rets = 0; goto free; } /* Offset needs to be cleaned for contiguous reads*/ if (cb->buf_idx == 0 && *offset > 0) *offset = 0; } else if (*offset > 0) { *offset = 0; } err = mei_cl_read_start(cl, length, file); if (err && err != -EBUSY) { cl_dbg(dev, cl, "mei start read failure status = %d\n", err); rets = err; goto out; } if (list_empty(&cl->rd_completed) && !waitqueue_active(&cl->rx_wait)) { if (file->f_flags & O_NONBLOCK) { rets = -EAGAIN; goto out; } mutex_unlock(&dev->device_lock); if (wait_event_interruptible(cl->rx_wait, (!list_empty(&cl->rd_completed)) || (!mei_cl_is_connected(cl)))) { if (signal_pending(current)) return -EINTR; return -ERESTARTSYS; } mutex_lock(&dev->device_lock); if (!mei_cl_is_connected(cl)) { rets = -EBUSY; goto out; } } cb = mei_cl_read_cb(cl, file); if (!cb) { if (mei_cl_is_fixed_address(cl) && dev->allow_fixed_address) { cb = mei_cl_read_cb(cl, NULL); if (cb) goto copy_buffer; } rets = 0; goto out; } copy_buffer: /* now copy the data to user space */ if (cb->status) { rets = cb->status; cl_dbg(dev, cl, "read operation failed %d\n", rets); goto free; } cl_dbg(dev, cl, "buf.size = %d buf.idx = %ld\n", cb->buf.size, cb->buf_idx); if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { rets = -EMSGSIZE; goto free; } /* length is being truncated to PAGE_SIZE, * however buf_idx may point beyond that */ length = min_t(size_t, length, cb->buf_idx - *offset); if (copy_to_user(ubuf, cb->buf.data + *offset, length)) { dev_dbg(dev->dev, "failed to copy data to userland\n"); rets = -EFAULT; goto free; } rets = length; *offset += length; if ((unsigned long)*offset < cb->buf_idx) goto out; free: mei_io_cb_free(cb); out: cl_dbg(dev, cl, "end mei read rets = %d\n", rets); mutex_unlock(&dev->device_lock); return rets; }
int wpa_ioctl(PSDevice pDevice, struct iw_point *p) { struct viawget_wpa_param *param; int ret = 0; int wpa_ioctl = 0; if (p->length < sizeof(struct viawget_wpa_param) || p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) return -EINVAL; param = kmalloc((int)p->length, (int)GFP_KERNEL); if (param == NULL) return -ENOMEM; if (copy_from_user(param, p->pointer, p->length)) { ret = -EFAULT; goto out; } switch (param->cmd) { case VIAWGET_SET_WPA: ret = wpa_set_wpa(pDevice, param); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n"); break; case VIAWGET_SET_KEY: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n"); spin_lock_irq(&pDevice->lock); ret = wpa_set_keys(pDevice, param, false); spin_unlock_irq(&pDevice->lock); break; case VIAWGET_SET_SCAN: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n"); ret = wpa_set_scan(pDevice, param); break; case VIAWGET_GET_SCAN: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n"); ret = wpa_get_scan(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_SSID: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n"); ret = wpa_get_ssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_BSSID: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n"); ret = wpa_get_bssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_SET_ASSOCIATE: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n"); ret = wpa_set_associate(pDevice, param); break; case VIAWGET_SET_DISASSOCIATE: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n"); ret = wpa_set_disassociate(pDevice, param); break; case VIAWGET_SET_DROP_UNENCRYPT: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n"); break; case VIAWGET_SET_DEAUTHENTICATE: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n"); break; default: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", param->cmd); return -EOPNOTSUPP; break; } if ((ret == 0) && wpa_ioctl) { if (copy_to_user(p->pointer, param, p->length)) { ret = -EFAULT; goto out; } } out: kfree(param); return ret; }
static int dn_def_dev_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { size_t len; struct net_device *dev; char devname[17]; if (!*lenp || (*ppos && !write)) { *lenp = 0; return 0; } if (write) { if (*lenp > 16) return -E2BIG; if (copy_from_user(devname, buffer, *lenp)) return -EFAULT; devname[*lenp] = 0; strip_it(devname); dev = dev_get_by_name(&init_net, devname); if (dev == NULL) return -ENODEV; if (dev->dn_ptr == NULL) { dev_put(dev); return -ENODEV; } if (dn_dev_set_default(dev, 1)) { dev_put(dev); return -ENODEV; } *ppos += *lenp; return 0; } dev = dn_dev_get_default(); if (dev == NULL) { *lenp = 0; return 0; } strcpy(devname, dev->name); dev_put(dev); len = strlen(devname); devname[len++] = '\n'; if (len > *lenp) len = *lenp; if (len > sizeof devname || copy_to_user(buffer, devname, len)) return -EFAULT; *lenp = len; *ppos += len; return 0; }
/* * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. */ static int dasd_ioctl_information(struct dasd_device *device, unsigned int cmd, void __user *argp) { struct dasd_information2_t *dasd_info; unsigned long flags; int rc; struct ccw_device *cdev; if (!device->discipline->fill_info) return -EINVAL; dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); if (dasd_info == NULL) return -ENOMEM; rc = device->discipline->fill_info(device, dasd_info); if (rc) { kfree(dasd_info); return rc; } cdev = device->cdev; dasd_info->devno = _ccw_device_get_device_number(device->cdev); dasd_info->schid = _ccw_device_get_subchannel_number(device->cdev); dasd_info->cu_type = cdev->id.cu_type; dasd_info->cu_model = cdev->id.cu_model; dasd_info->dev_type = cdev->id.dev_type; dasd_info->dev_model = cdev->id.dev_model; dasd_info->status = device->state; /* * The open_count is increased for every opener, that includes * the blkdev_get in dasd_scan_partitions. * This must be hidden from user-space. */ dasd_info->open_count = atomic_read(&device->open_count); if (!device->bdev) dasd_info->open_count++; /* * check if device is really formatted * LDL / CDL was returned by 'fill_info' */ if ((device->state < DASD_STATE_READY) || (dasd_check_blocksize(device->bp_block))) dasd_info->format = DASD_FORMAT_NONE; dasd_info->features |= ((device->features & DASD_FEATURE_READONLY) != 0); if (device->discipline) memcpy(dasd_info->type, device->discipline->name, 4); else memcpy(dasd_info->type, "none", 4); if (device->request_queue->request_fn) { struct list_head *l; #ifdef DASD_EXTENDED_PROFILING { struct list_head *l; spin_lock_irqsave(&device->lock, flags); list_for_each(l, &device->request_queue->queue_head) dasd_info->req_queue_len++; spin_unlock_irqrestore(&device->lock, flags); } #endif /* DASD_EXTENDED_PROFILING */ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); list_for_each(l, &device->ccw_queue) dasd_info->chanq_len++; spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); } rc = 0; if (copy_to_user(argp, dasd_info, ((cmd == (unsigned int) BIODASDINFO2) ? sizeof (struct dasd_information2_t) : sizeof (struct dasd_information_t)))) rc = -EFAULT; kfree(dasd_info); return rc; }
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "SBC60xx", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); } /* Fall through */ case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit sbc60xxwdt_unload(void) { wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) release_region(wdt_stop, 1); release_region(wdt_start, 1); } static int __init sbc60xxwdt_init(void) { int rc = -EBUSY; if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; pr_info("timeout value must be 1 <= x <= 3600, using %d\n", timeout); } if (!request_region(wdt_start, 1, "SBC 60XX WDT")) { pr_err("I/O address 0x%04x already in use\n", wdt_start); rc = -EIO; goto err_out; } /* We cannot reserve 0x45 - the kernel already has! */ if (wdt_stop != 0x45 && wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) { pr_err("I/O address 0x%04x already in use\n", wdt_stop); rc = -EIO; goto err_out_region1; } } rc = register_reboot_notifier(&wdt_notifier); if (rc) { pr_err("cannot register reboot notifier (err=%d)\n", rc); goto err_out_region2; } rc = misc_register(&wdt_miscdev); if (rc) { pr_err("cannot register miscdev on minor=%d (err=%d)\n", wdt_miscdev.minor, rc); goto err_out_reboot; } pr_info("WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; err_out_reboot: unregister_reboot_notifier(&wdt_notifier); err_out_region2: if (wdt_stop != 0x45 && wdt_stop != wdt_start) release_region(wdt_stop, 1); err_out_region1: release_region(wdt_start, 1); err_out: return rc; }
static int ar2315_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; int new_heartbeat; int status = 0; static struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .firmware_version = 1, .identity = "ar2315", }; switch(cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: //wdt_get_status(&status); return put_user(status, p); case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: ar2315_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (ar2315_wdt_set_heartbeat(new_heartbeat)) return -EINVAL; ar2315_wdt_ping(); /* fallthrough */ case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); } } static struct file_operations ar2315_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = ar2315_wdt_write, .ioctl = ar2315_wdt_ioctl, .open = ar2315_wdt_open, .release = ar2315_wdt_release, }; static struct miscdevice ar2315_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &ar2315_wdt_fops, }; static int __init ar2315_wdt_init(void) { int ret = 0; if (ar2315_wdt_set_heartbeat(heartbeat)) { ar2315_wdt_set_heartbeat(5); printk(KERN_INFO "%s: heartbeat value must be 0<heartbeat<90, using %d\n", __func__, 5); } ar2315_wdt_print_info(); ar2315_wdt_ping(); printk("%s using heartbeat %d s cycles %u\n", __func__, heartbeat, S_TO_CYCLES(heartbeat)); ret = request_irq(AR531X_MISC_IRQ_WATCHDOG, ar2315_wdt_interrupt, SA_INTERRUPT, "ar2315_wdt", NULL); ar2315_wdt_print_info(); if (ret) { printk(KERN_ERR "wdt: IRQ %d is not free.\n", AR531X_MISC_IRQ_WATCHDOG); goto out; } ret = misc_register(&ar2315_wdt_miscdev); if (ret) { printk(KERN_ERR "%s: cannot register miscdev on minor=%d (err=%d)\n", __func__, WATCHDOG_MINOR, ret); goto out1; } out: return ret; out1: misc_deregister(&ar2315_wdt_miscdev); return ret; } static void __exit ar2315_wdt_exit(void) { printk("%s\n", __func__); misc_deregister(&ar2315_wdt_miscdev); free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL); }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(INFO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static int mtd_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; int ret = 0; u_long size; DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (cmd & IOC_IN) { ret = verify_area(VERIFY_READ, (char *)arg, size); if (ret) return ret; } if (cmd & IOC_OUT) { ret = verify_area(VERIFY_WRITE, (char *)arg, size); if (ret) return ret; } switch (cmd) { case MEMGETREGIONCOUNT: if (copy_to_user((int *) arg, &(mtd->numeraseregions), sizeof(int))) return -EFAULT; break; case MEMGETREGIONINFO: { struct region_info_user ur; if (copy_from_user( &ur, (struct region_info_user *)arg, sizeof(struct region_info_user))) { return -EFAULT; } if (ur.regionindex >= mtd->numeraseregions) return -EINVAL; if (copy_to_user((struct mtd_erase_region_info *) arg, &(mtd->eraseregions[ur.regionindex]), sizeof(struct mtd_erase_region_info))) return -EFAULT; break; } case MEMGETINFO: if (copy_to_user((struct mtd_info *)arg, mtd, sizeof(struct mtd_info_user))) return -EFAULT; break; case MEMERASE: { struct erase_info *erase=kmalloc(sizeof(struct erase_info),GFP_KERNEL); if (!erase) ret = -ENOMEM; else { wait_queue_head_t waitq; DECLARE_WAITQUEUE(wait, current); init_waitqueue_head(&waitq); memset (erase,0,sizeof(struct erase_info)); if (copy_from_user(&erase->addr, (u_long *)arg, 2 * sizeof(u_long))) { kfree(erase); return -EFAULT; } erase->mtd = mtd; erase->callback = mtd_erase_callback; erase->priv = (unsigned long)&waitq; /* FIXME: Allow INTERRUPTIBLE. Which means not having the wait_queue head on the stack. If the wq_head is on the stack, and we leave because we got interrupted, then the wq_head is no longer there when the callback routine tries to wake us up. */ ret = mtd->erase(mtd, erase); if (!ret) { set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&waitq, &wait); if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED) schedule(); remove_wait_queue(&waitq, &wait); set_current_state(TASK_RUNNING); ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0; } kfree(erase); } break; } case MEMWRITEOOB: { struct mtd_oob_buf buf; void *databuf; ssize_t retlen; if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) return -EINVAL; if (!mtd->write_oob) ret = -EOPNOTSUPP; else ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length); if (ret) return ret; databuf = kmalloc(buf.length, GFP_KERNEL); if (!databuf) return -ENOMEM; if (copy_from_user(databuf, buf.ptr, buf.length)) { kfree(databuf); return -EFAULT; } ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf); if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; kfree(databuf); break; } case MEMREADOOB: { struct mtd_oob_buf buf; void *databuf; ssize_t retlen; if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) return -EINVAL; if (!mtd->read_oob) ret = -EOPNOTSUPP; else ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length); if (ret) return ret; databuf = kmalloc(buf.length, GFP_KERNEL); if (!databuf) return -ENOMEM; ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) ret = -EFAULT; kfree(databuf); break; } case MEMLOCK: { unsigned long adrs[2]; if (copy_from_user(adrs ,(void *)arg, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->lock) ret = -EOPNOTSUPP; else ret = mtd->lock(mtd, adrs[0], adrs[1]); break; } case MEMUNLOCK: { unsigned long adrs[2]; if (copy_from_user(adrs, (void *)arg, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->unlock) ret = -EOPNOTSUPP; else ret = mtd->unlock(mtd, adrs[0], adrs[1]); break; } default: DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO); ret = -ENOTTY; } return ret; } /* memory_ioctl */
ssize_t wmt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { INT32 retval = 0; INT32 i_ret = 0; CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; if(*f_pos > 0){ retval = 0; } else { /*len = sprintf(page, "%d\n", g_psm_enable);*/ if ( gCoexBuf.availSize <= 0) { WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); retval = osal_strlen(warn_msg) + 1; if (count < retval) { retval = count; } i_ret = copy_to_user(buf, warn_msg, retval); if (i_ret) { WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); retval = -EFAULT; goto err_exit; } *f_pos += retval; } else { INT32 i = 0; INT32 len = 0; CHAR msg_info[128]; INT32 max_num = 0; /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page buffer is not enough, a bomb is placed here on unexpected condition*/ WMT_INFO_FUNC("%d bytes avaliable\n", gCoexBuf.availSize); max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) -1) / 5; if (max_num > gCoexBuf.availSize) { max_num = gCoexBuf.availSize; } else { WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); } for (i = 0; i < max_num; i++) { len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); } len += osal_sprintf(msg_info + len, "\n"); retval = len; i_ret = copy_to_user(buf, msg_info, retval); if (i_ret) { WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); retval = -EFAULT; goto err_exit; } *f_pos += retval; } } gCoexBuf.availSize = 0; err_exit: return retval; }
static long indydog_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int options, retval = -EINVAL; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING, .firmware_version = 0, .identity = "Hardware Watchdog for SGI IP22", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_SETOPTIONS: { if (get_user(options, (int *)arg)) return -EFAULT; if (options & WDIOS_DISABLECARD) { indydog_stop(); retval = 0; } if (options & WDIOS_ENABLECARD) { indydog_start(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: indydog_ping(); return 0; case WDIOC_GETTIMEOUT: return put_user(WATCHDOG_TIMEOUT, (int *)arg); default: return -ENOTTY; } } static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) indydog_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static const struct file_operations indydog_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = indydog_write, .unlocked_ioctl = indydog_ioctl, .open = indydog_open, .release = indydog_release, }; static struct miscdevice indydog_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &indydog_fops, }; static struct notifier_block indydog_notifier = { .notifier_call = indydog_notify_sys, }; static int __init watchdog_init(void) { int ret; ret = register_reboot_notifier(&indydog_notifier); if (ret) { pr_err("cannot register reboot notifier (err=%d)\n", ret); return ret; } ret = misc_register(&indydog_miscdev); if (ret) { pr_err("cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); unregister_reboot_notifier(&indydog_notifier); return ret; } pr_info("Hardware Watchdog Timer for SGI IP22: 0.3\n"); return 0; } static void __exit watchdog_exit(void) { misc_deregister(&indydog_miscdev); unregister_reboot_notifier(&indydog_notifier); }
static long tcc_dxb_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret; unsigned int deviceIdx; unsigned int uiboardtype; unsigned int uirfpathctrl; ST_CTRLINFO_ARG stCtrlInfo; struct tcc_dxb_platform_data *dxb_dev; dxb_dev = (struct tcc_dxb_platform_data *)pdev_dxb->platform_data; switch (cmd) { case IOCTL_DXB_CTRL_OFF: if(arg!=0) { deviceIdx = *(unsigned int *)arg; dxb_dev->power_off(deviceIdx); } else { dxb_dev->power_off(0); } break; case IOCTL_DXB_CTRL_ON: if(arg!=0) { deviceIdx = *(unsigned int *)arg; dxb_dev->power_on(deviceIdx); } else { dxb_dev->power_on(0); } break; case IOCTL_DXB_CTRL_RF_PATH: ret = copy_from_user((void*)&uirfpathctrl, (const void*)arg, sizeof(unsigned long)); dxb_dev->rf_path(uirfpathctrl); break; case IOCTL_DXB_CTRL_RESET: if(arg!=0) { deviceIdx = *(unsigned int *)arg; dxb_dev->power_reset(deviceIdx); } else { dxb_dev->power_reset(0); } break; case IOCTL_DXB_CTRL_SET_BOARD: ret = copy_from_user((void *)&uiboardtype, (const void *)arg, sizeof(unsigned long)); if(uiboardtype < BOARD_MAX) { dxb_dev->set_board(uiboardtype); } break; case IOCTL_DXB_CTRL_GET_CTLINFO: dxb_dev->get_info(&stCtrlInfo); ret = copy_to_user((ST_CTRLINFO_ARG *)arg, &stCtrlInfo, sizeof(ST_CTRLINFO_ARG)); break; default: printk("bl: unrecognized ioctl (0x%x)\n", cmd); return -EINVAL; break; } return 0; }