Commit e5617d2b authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: bus: use zero vtag for bus clients.



The zero vtag is required for the read flow to work also for
devices on the mei client bus.

Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20200818115147.2567012-10-tomas.winkler@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 15ffa991
Loading
Loading
Loading
Loading
+71 −1
Original line number Diff line number Diff line
@@ -495,6 +495,68 @@ static void mei_cl_bus_module_put(struct mei_cl_device *cldev)
	module_put(cldev->bus->dev->driver->owner);
}

/**
 * mei_cl_bus_vtag - get bus vtag entry wrapper
 *     The tag for bus client is always first.
 *
 * @cl: host client
 *
 * Return: bus vtag or NULL
 */
static inline struct mei_cl_vtag *mei_cl_bus_vtag(struct mei_cl *cl)
{
	return list_first_entry_or_null(&cl->vtag_map,
					struct mei_cl_vtag, list);
}

/**
 * mei_cl_bus_vtag_alloc - add bus client entry to vtag map
 *
 * @cldev: me client device
 *
 * Return:
 * * 0 on success
 * * -ENOMEM if memory allocation failed
 */
static int mei_cl_bus_vtag_alloc(struct mei_cl_device *cldev)
{
	struct mei_cl *cl = cldev->cl;
	struct mei_cl_vtag *cl_vtag;

	/*
	 * Bail out if the client does not supports vtags
	 * or has already allocated one
	 */
	if (mei_cl_vt_support_check(cl) || mei_cl_bus_vtag(cl))
		return 0;

	cl_vtag = mei_cl_vtag_alloc(NULL, 0);
	if (IS_ERR(cl_vtag))
		return -ENOMEM;

	list_add_tail(&cl_vtag->list, &cl->vtag_map);

	return 0;
}

/**
 * mei_cl_bus_vtag_free - remove the bus entry from vtag map
 *
 * @cldev: me client device
 */
static void mei_cl_bus_vtag_free(struct mei_cl_device *cldev)
{
	struct mei_cl *cl = cldev->cl;
	struct mei_cl_vtag *cl_vtag;

	cl_vtag = mei_cl_bus_vtag(cl);
	if (!cl_vtag)
		return;

	list_del(&cl_vtag->list);
	kfree(cl_vtag);
}

/**
 * mei_cldev_enable - enable me client device
 *     create connection with me client
@@ -531,9 +593,15 @@ int mei_cldev_enable(struct mei_cl_device *cldev)
		goto out;
	}

	ret = mei_cl_bus_vtag_alloc(cldev);
	if (ret)
		goto out;

	ret = mei_cl_connect(cl, cldev->me_cl, NULL);
	if (ret < 0)
	if (ret < 0) {
		dev_err(&cldev->dev, "cannot connect\n");
		mei_cl_bus_vtag_free(cldev);
	}

out:
	mutex_unlock(&bus->device_lock);
@@ -586,6 +654,8 @@ int mei_cldev_disable(struct mei_cl_device *cldev)

	mutex_lock(&bus->device_lock);

	mei_cl_bus_vtag_free(cldev);

	if (!mei_cl_is_connected(cl)) {
		dev_dbg(bus->dev, "Already disconnected\n");
		err = 0;