static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; void *wbuf; struct rmnet_ctrl_dev *dev = file->private_data; if (!dev) return -ENODEV; if (size <= 0) return -EINVAL; if (!is_dev_connected(dev)) return -ENETRESET; if (!dev->is_opened) return size; if (dev->tx_block) { pr_info("%s: tx blocked by reset, just return\n", __func__); return size; } DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); wbuf = kmalloc(size , GFP_KERNEL); if (!wbuf) return -ENOMEM; status = copy_from_user(wbuf , buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); return status; } DUMP_BUFFER("Write: ", size, buf); status = rmnet_usb_ctrl_write(dev, wbuf, size); if (status == size) return size; return status; }
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; size_t total_len; void *wbuf; void *actual_data; struct ctrl_pkt *cpkt; struct rmnet_ctrl_dev *dev = file->private_data; rewrite: if (!dev) return -ENODEV; if (!size) return -EINVAL; if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) return -ENETRESET; DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); total_len = size; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4); wbuf = kmalloc(total_len , GFP_KERNEL); if (!wbuf) return -ENOMEM; cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL); if (!cpkt) { kfree(wbuf); return -ENOMEM; } actual_data = cpkt->data = wbuf; cpkt->data_size = total_len; cpkt->ctxt = dev; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) { actual_data = wbuf + sizeof(struct mux_hdr); rmnet_usb_ctrl_mux(dev->ch_id, cpkt); } status = copy_from_user(actual_data, buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); kfree(cpkt); return status; } DUMP_BUFFER("Write: ", size, buf); status = rmnet_usb_ctrl_write(dev, cpkt, size); if (status == size) return size; else if (status == -EAGAIN) { dev_err(dev->devicep, "%s: rewrite\n", __func__); goto rewrite; } return status; }
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; size_t total_len; void *wbuf; void *actual_data; struct ctrl_pkt *cpkt; struct rmnet_ctrl_dev *dev = file->private_data; if (!dev) return -ENODEV; if (size <= 0) return -EINVAL; if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) return -ENETRESET; DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); #ifdef CONFIG_QCT_9K_MODEM if (get_radio_flag() & RADIO_FLAG_MORE_LOG) pr_info("[RMNET] W: %i\n", size); #endif total_len = size; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4); wbuf = kmalloc(total_len , GFP_KERNEL); if (!wbuf) return -ENOMEM; cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL); if (!cpkt) { kfree(wbuf); return -ENOMEM; } actual_data = cpkt->data = wbuf; cpkt->data_size = total_len; cpkt->ctxt = dev; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) { actual_data = wbuf + sizeof(struct mux_hdr); rmnet_usb_ctrl_mux(dev->ch_id, cpkt); } status = copy_from_user(actual_data, buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); kfree(cpkt); return status; } DUMP_BUFFER("Write: ", size, buf); #ifdef CONFIG_QCT_9K_MODEM status = rmnet_usb_ctrl_write(dev, cpkt, size); if (status == size) return size; else pr_err("[%s] status %d\n", __func__, status); #else status = rmnet_usb_ctrl_write_cmd(dev->cudev, USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, cpkt->data, cpkt->data_size); if (status > 0) dev->cudev->snd_encap_cmd_cnt++; kfree(cpkt->data); kfree(cpkt); #endif return status; }