Пример #1
0
int rmnet_usb_ctrl_init(int no_rmnet_devs, int no_rmnet_insts_per_dev)
{
	struct rmnet_ctrl_dev	*dev;
	int			i, n;
	int			status;

	num_devs = no_rmnet_devs;
	insts_per_dev = no_rmnet_insts_per_dev;

	ctrl_devs = kzalloc(num_devs * sizeof(*ctrl_devs), GFP_KERNEL);
	if (!ctrl_devs)
		return -ENOMEM;

	for (i = 0; i < num_devs; i++) {
		ctrl_devs[i] = kzalloc(insts_per_dev * sizeof(*ctrl_devs[i]),
				       GFP_KERNEL);
		if (!ctrl_devs[i])
			return -ENOMEM;

		status = alloc_chrdev_region(&ctrldev_num[i], 0, insts_per_dev,
					     rmnet_dev_names[i]);
		if (IS_ERR_VALUE(status)) {
			pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
				__func__, status);
			return status;
		}

		ctrldev_classp[i] = class_create(THIS_MODULE,
						 rmnet_dev_names[i]);
		if (IS_ERR(ctrldev_classp[i])) {
			pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
			status = PTR_ERR(ctrldev_classp[i]);
			return status;
		}

		for (n = 0; n < insts_per_dev; n++) {
			dev = &ctrl_devs[i][n];

			/*for debug purpose*/
			snprintf(dev->name, CTRL_DEV_MAX_LEN, "%s%d",
				 rmnet_dev_names[i], n);

			dev->wq = create_singlethread_workqueue(dev->name);
			if (!dev->wq) {
				pr_err("unable to allocate workqueue");
				kfree(dev);
				return -ENOMEM;
			}

			dev->ch_id = n;

			mutex_init(&dev->dev_lock);
			spin_lock_init(&dev->rx_lock);
			init_waitqueue_head(&dev->read_wait_queue);
			init_waitqueue_head(&dev->open_wait_queue);
			INIT_LIST_HEAD(&dev->rx_list);
			init_usb_anchor(&dev->tx_submitted);
			init_usb_anchor(&dev->rx_submitted);
			INIT_WORK(&dev->get_encap_work, get_encap_work);

			cdev_init(&dev->cdev, &ctrldev_fops);
			dev->cdev.owner = THIS_MODULE;

			status = cdev_add(&dev->cdev, (ctrldev_num[i] + n), 1);
			if (status) {
				pr_err("%s: cdev_add() ret %i\n", __func__,
					status);
				destroy_workqueue(dev->wq);
				kfree(dev);
				return status;
			}

			dev->devicep = device_create(ctrldev_classp[i], NULL,
						     (ctrldev_num[i] + n), NULL,
						     "%s%d", rmnet_dev_names[i],
						     n);
			if (IS_ERR(dev->devicep)) {
				pr_err("%s: device_create() returned %ld\n",
					__func__, PTR_ERR(dev->devicep));
				cdev_del(&dev->cdev);
				destroy_workqueue(dev->wq);
				kfree(dev);
				return PTR_ERR(dev->devicep);
			}

			/*create /sys/class/hsicctl/hsicctlx/modem_wait*/
			status = device_create_file(dev->devicep,
						    &dev_attr_modem_wait);
			if (status) {
				device_destroy(dev->devicep->class,
					       dev->devicep->devt);
				cdev_del(&dev->cdev);
				destroy_workqueue(dev->wq);
				kfree(dev);
				return status;
			}
			dev_set_drvdata(dev->devicep, dev);

			status = rmnet_usb_ctrl_alloc_rx(dev);
			if (status) {
				device_remove_file(dev->devicep,
						   &dev_attr_modem_wait);
				device_destroy(dev->devicep->class,
					       dev->devicep->devt);
				cdev_del(&dev->cdev);
				destroy_workqueue(dev->wq);
				kfree(dev);
				return status;
			}
		}
	}

	rmnet_usb_ctrl_debugfs_init();
	pr_info("rmnet usb ctrl Initialized.\n");
	return 0;
}
Пример #2
0
int rmnet_usb_ctrl_init(void)
{
	struct rmnet_ctrl_dev	*dev;
	int			n;
	int			status;

	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			status = -ENOMEM;
			goto error0;
		}
		/*for debug purpose*/
		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);

		dev->wq = create_singlethread_workqueue(dev->name);
		if (!dev->wq) {
			pr_err("unable to allocate workqueue");
			kfree(dev);
			goto error0;
		}

		mutex_init(&dev->dev_lock);
		spin_lock_init(&dev->rx_lock);
		init_waitqueue_head(&dev->read_wait_queue);
		init_waitqueue_head(&dev->open_wait_queue);
		INIT_LIST_HEAD(&dev->rx_list);
		init_usb_anchor(&dev->tx_submitted);
		init_usb_anchor(&dev->rx_submitted);
		INIT_WORK(&dev->get_encap_work, get_encap_work);

		status = rmnet_usb_ctrl_alloc_rx(dev);
		if (status < 0) {
			kfree(dev);
			goto error0;
		}

		ctrl_dev[n] = dev;
	}

	status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS,
			DEVICE_NAME);
	if (IS_ERR_VALUE(status)) {
		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
		       __func__, status);
		goto error0;
	}

	ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(ctrldev_classp)) {
		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
		status = -ENOMEM;
		goto error1;
	}
	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
		cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops);
		ctrl_dev[n]->cdev.owner = THIS_MODULE;

		status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1);

		if (IS_ERR_VALUE(status)) {
			pr_err("%s: cdev_add() ret %i\n", __func__, status);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		ctrl_dev[n]->devicep =
				device_create(ctrldev_classp, NULL,
				(ctrldev_num + n), NULL,
				DEVICE_NAME "%d", n);

		if (IS_ERR(ctrl_dev[n]->devicep)) {
			pr_err("%s: device_create() ENOMEM\n", __func__);
			status = -ENOMEM;
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		/*create /sys/class/hsicctl/hsicctlx/modem_wait*/
		status = device_create_file(ctrl_dev[n]->devicep,
					&dev_attr_modem_wait);
		if (status) {
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]);
	}

	rmnet_usb_ctrl_debugfs_init();
	pr_info("rmnet usb ctrl Initialized.\n");
	return 0;

error2:
		while (--n >= 0) {
			cdev_del(&ctrl_dev[n]->cdev);
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
		}

		class_destroy(ctrldev_classp);
		n = NUM_CTRL_CHANNELS;
error1:
	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
error0:
	while (--n >= 0)
		kfree(ctrl_dev[n]);

	return status;
}
int rmnet_usb_ctrl_init(void)
{
	struct rmnet_ctrl_dev	*dev;
	int			n;
	int			status;
	int			ret = 0;

	
	if (get_radio_flag() & 0x0001)
		usb_pm_debug_enabled  = true;

	if (get_radio_flag() & 0x0002)
		enable_ctl_msg_debug = true;
	

#ifdef HTC_LOG_RMNET_USB_CTRL
	if (get_radio_flag() & 0x0008)
		enable_dbg_rmnet_usb_ctrl = true;
#endif	

	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			status = -ENOMEM;
			goto error0;
		}
		
		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);

		dev->wq = create_singlethread_workqueue(dev->name);
		if (!dev->wq) {
			pr_err("unable to allocate workqueue");
			kfree(dev);
			goto error0;
		}

		mutex_init(&dev->dev_lock);
		spin_lock_init(&dev->rx_lock);
		init_waitqueue_head(&dev->read_wait_queue);
		init_waitqueue_head(&dev->open_wait_queue);
		INIT_LIST_HEAD(&dev->rx_list);
		init_usb_anchor(&dev->tx_submitted);
		init_usb_anchor(&dev->rx_submitted);
		INIT_WORK(&dev->get_encap_work, get_encap_work);

		status = rmnet_usb_ctrl_alloc_rx(dev);
		if (status < 0) {
			kfree(dev);
			goto error0;
		}

		ctrl_dev[n] = dev;
	}

	status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS,
			DEVICE_NAME);
	if (IS_ERR_VALUE(status)) {
		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
		       __func__, status);
		goto error0;
	}

	ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(ctrldev_classp)) {
		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
		status = -ENOMEM;
		goto error1;
	}
	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
		cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops);
		ctrl_dev[n]->cdev.owner = THIS_MODULE;

		status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1);

		if (IS_ERR_VALUE(status)) {
			pr_err("%s: cdev_add() ret %i\n", __func__, status);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		ctrl_dev[n]->devicep =
				device_create(ctrldev_classp, NULL,
				(ctrldev_num + n), NULL,
				DEVICE_NAME "%d", n);

		if (IS_ERR(ctrl_dev[n]->devicep)) {
			pr_err("%s: device_create() ENOMEM\n", __func__);
			status = -ENOMEM;
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		
		status = device_create_file(ctrl_dev[n]->devicep,
					&dev_attr_modem_wait);
		if (status) {
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]);
	}

	rmnet_usb_ctrl_debugfs_init();
	do {
		pr_info("%s: register_chrdev\n", __func__);
		ret = register_chrdev(0, HTC_HSIC_DEVICE_NAME, &hsicctrldev_fops);
		if ( ret < 0 ) {
			pr_err("%s: register_chrdev, ret=[%d]\n", __func__, ret);
			break;
		}
		pr_info("%s: register_chrdev, ret=[%d]\n", __func__, ret);
		htc_hsicctrldev_major = ret;
		pr_info("%s: class_create\n", __func__);
		hsicctrldev_classp = class_create(THIS_MODULE, HTC_HSIC_DEVICE_NAME);
		if (IS_ERR(hsicctrldev_classp)) {
			pr_err("%s: class_create() ENOMEM\n", __func__);
			unregister_chrdev( htc_hsicctrldev_major, HTC_HSIC_DEVICE_NAME );
			break;
		}
		pr_info("%s: device_create\n", __func__);
		hsicdevicep = device_create(hsicctrldev_classp, NULL, MKDEV(htc_hsicctrldev_major, 0), NULL, HTC_HSIC_DEVICE_NAME);
		if (IS_ERR(hsicdevicep)) {
			pr_err("%s: device_create() ENOMEM\n", __func__);
			class_destroy(hsicctrldev_classp);
			hsicctrldev_classp = NULL;
			hsicdevicep = NULL;
			break;
		}
	}
	while ( 0 );

	pr_info("rmnet usb ctrl Initialized.\n");
	return 0;
error2:
		while (--n >= 0) {
			cdev_del(&ctrl_dev[n]->cdev);
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
		}

		class_destroy(ctrldev_classp);
		n = NUM_CTRL_CHANNELS;
error1:
	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
error0:
	while (--n >= 0)
		kfree(ctrl_dev[n]);

	return status;
}