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;
}
Exemple #3
0
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;
}