示例#1
0
文件: nfc.c 项目: Abioy/kasan
void mei_nfc_host_exit(struct mei_device *dev)
{
	struct mei_nfc_dev *ndev;
	struct mei_cl *cl;
	struct mei_cl_device *cldev;

	cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid);
	if (!cl)
		return;

	cldev = cl->device;
	if (!cldev)
		return;

	ndev = (struct mei_nfc_dev *)cldev->priv_data;
	if (ndev)
		cancel_work_sync(&ndev->init_work);

	cldev->priv_data = NULL;

	mutex_lock(&dev->device_lock);
	/* Need to remove the device here
	 * since mei_nfc_free will unlink the clients
	 */
	mei_cl_remove_device(cldev);
	mei_nfc_free(ndev);
	mutex_unlock(&dev->device_lock);
}
示例#2
0
void mei_nfc_host_exit(void)
{
	struct mei_nfc_dev *ndev = &nfc_dev;

	if (ndev->cl && ndev->cl->device)
		mei_cl_remove_device(ndev->cl->device);

	mei_nfc_free(ndev);
}
示例#3
0
文件: nfc.c 项目: Abioy/kasan
int mei_nfc_host_init(struct mei_device *dev)
{
	struct mei_nfc_dev *ndev;
	struct mei_cl *cl_info, *cl = NULL;
	struct mei_me_client *me_cl;
	int ret;


	/* in case of internal reset bail out
	 * as the device is already setup
	 */
	cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid);
	if (cl)
		return 0;

	ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL);
	if (!ndev) {
		ret = -ENOMEM;
		goto err;
	}

	ndev->cl_info = mei_cl_allocate(dev);
	ndev->cl = mei_cl_allocate(dev);

	cl = ndev->cl;
	cl_info = ndev->cl_info;

	if (!cl || !cl_info) {
		ret = -ENOMEM;
		goto err;
	}

	/* check for valid client id */
	me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid);
	if (!me_cl) {
		dev_info(dev->dev, "nfc: failed to find the client\n");
		ret = -ENOTTY;
		goto err;
	}

	cl_info->me_client_id = me_cl->client_id;
	cl_info->cl_uuid = me_cl->props.protocol_name;
	mei_me_cl_put(me_cl);

	ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY);
	if (ret)
		goto err;


	list_add_tail(&cl_info->device_link, &dev->device_list);

	/* check for valid client id */
	me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid);
	if (!me_cl) {
		dev_info(dev->dev, "nfc: failed to find the client\n");
		ret = -ENOTTY;
		goto err;
	}

	cl->me_client_id = me_cl->client_id;
	cl->cl_uuid = me_cl->props.protocol_name;
	mei_me_cl_put(me_cl);

	ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
	if (ret)
		goto err;

	list_add_tail(&cl->device_link, &dev->device_list);

	ndev->req_id = 1;

	INIT_WORK(&ndev->init_work, mei_nfc_init);
	init_waitqueue_head(&ndev->send_wq);
	schedule_work(&ndev->init_work);

	return 0;

err:
	mei_nfc_free(ndev);

	return ret;
}
示例#4
0
文件: nfc.c 项目: Abioy/kasan
static void mei_nfc_init(struct work_struct *work)
{
	struct mei_device *dev;
	struct mei_cl_device *cldev;
	struct mei_nfc_dev *ndev;
	struct mei_cl *cl_info;

	ndev = container_of(work, struct mei_nfc_dev, init_work);

	cl_info = ndev->cl_info;
	dev = cl_info->dev;

	mutex_lock(&dev->device_lock);

	if (mei_cl_connect(cl_info, NULL) < 0) {
		mutex_unlock(&dev->device_lock);
		dev_err(dev->dev, "Could not connect to the NFC INFO ME client");

		goto err;
	}

	mutex_unlock(&dev->device_lock);

	if (mei_nfc_if_version(ndev) < 0) {
		dev_err(dev->dev, "Could not get the NFC interface version");

		goto err;
	}

	dev_info(dev->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n",
		ndev->fw_ivn, ndev->vendor_id, ndev->radio_type);

	mutex_lock(&dev->device_lock);

	if (mei_cl_disconnect(cl_info) < 0) {
		mutex_unlock(&dev->device_lock);
		dev_err(dev->dev, "Could not disconnect the NFC INFO ME client");

		goto err;
	}

	mutex_unlock(&dev->device_lock);

	if (mei_nfc_build_bus_name(ndev) < 0) {
		dev_err(dev->dev, "Could not build the bus ID name\n");
		return;
	}

	cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops);
	if (!cldev) {
		dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n");

		goto err;
	}

	cldev->priv_data = ndev;


	return;

err:
	mutex_lock(&dev->device_lock);
	mei_nfc_free(ndev);
	mutex_unlock(&dev->device_lock);

}
示例#5
0
int mei_nfc_host_init(struct mei_device *dev)
{
	struct mei_nfc_dev *ndev = &nfc_dev;
	struct mei_cl *cl_info, *cl = NULL;
	int i, ret;

	/* already initialzed */
	if (ndev->cl_info)
		return 0;

	ndev->cl_info = mei_cl_allocate(dev);
	ndev->cl = mei_cl_allocate(dev);

	cl = ndev->cl;
	cl_info = ndev->cl_info;

	if (!cl || !cl_info) {
		ret = -ENOMEM;
		goto err;
	}

	/* check for valid client id */
	i = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid);
	if (i < 0) {
		dev_info(&dev->pdev->dev, "nfc: failed to find the client\n");
		ret = -ENOENT;
		goto err;
	}

	cl_info->me_client_id = dev->me_clients[i].client_id;

	ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY);
	if (ret)
		goto err;

	cl_info->device_uuid = mei_nfc_info_guid;

	list_add_tail(&cl_info->device_link, &dev->device_list);

	/* check for valid client id */
	i = mei_me_cl_by_uuid(dev, &mei_nfc_guid);
	if (i < 0) {
		dev_info(&dev->pdev->dev, "nfc: failed to find the client\n");
		ret = -ENOENT;
		goto err;
	}

	cl->me_client_id = dev->me_clients[i].client_id;

	ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
	if (ret)
		goto err;

	cl->device_uuid = mei_nfc_guid;


	list_add_tail(&cl->device_link, &dev->device_list);

	ndev->req_id = 1;

	INIT_WORK(&ndev->init_work, mei_nfc_init);
	init_waitqueue_head(&ndev->send_wq);
	schedule_work(&ndev->init_work);

	return 0;

err:
	mei_nfc_free(ndev);

	return ret;
}