Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2 * Intel Management Engine Interface (Intel MEI) Linux driver
   3 * Copyright (c) 2012-2013, Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/device.h>
  18#include <linux/kernel.h>
  19#include <linux/sched.h>
  20#include <linux/init.h>
  21#include <linux/errno.h>
  22#include <linux/slab.h>
  23#include <linux/mutex.h>
  24#include <linux/interrupt.h>
  25#include <linux/mei_cl_bus.h>
  26
  27#include "mei_dev.h"
  28#include "client.h"
  29
  30#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
  31#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
  32
  33/**
  34 * __mei_cl_send - internal client send (write)
  35 *
  36 * @cl: host client
  37 * @buf: buffer to send
  38 * @length: buffer length
  39 * @mode: sending mode
  40 *
  41 * Return: written size bytes or < 0 on error
  42 */
  43ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
  44		      unsigned int mode)
  45{
  46	struct mei_device *bus;
  47	struct mei_cl_cb *cb;
  48	ssize_t rets;
  49
  50	if (WARN_ON(!cl || !cl->dev))
  51		return -ENODEV;
  52
  53	bus = cl->dev;
  54
  55	mutex_lock(&bus->device_lock);
  56	if (bus->dev_state != MEI_DEV_ENABLED) {
  57		rets = -ENODEV;
  58		goto out;
  59	}
  60
  61	if (!mei_cl_is_connected(cl)) {
  62		rets = -ENODEV;
  63		goto out;
  64	}
  65
  66	/* Check if we have an ME client device */
  67	if (!mei_me_cl_is_active(cl->me_cl)) {
  68		rets = -ENOTTY;
  69		goto out;
  70	}
  71
  72	if (length > mei_cl_mtu(cl)) {
  73		rets = -EFBIG;
  74		goto out;
  75	}
  76
  77	cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
  78	if (!cb) {
  79		rets = -ENOMEM;
  80		goto out;
  81	}
  82
  83	cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
  84	cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
  85	memcpy(cb->buf.data, buf, length);
  86
  87	rets = mei_cl_write(cl, cb);
  88
  89out:
  90	mutex_unlock(&bus->device_lock);
  91
  92	return rets;
  93}
  94
  95/**
  96 * __mei_cl_recv - internal client receive (read)
  97 *
  98 * @cl: host client
  99 * @buf: buffer to receive
 100 * @length: buffer length
 101 * @mode: io mode
 102 *
 103 * Return: read size in bytes of < 0 on error
 104 */
 105ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
 106		      unsigned int mode)
 107{
 108	struct mei_device *bus;
 109	struct mei_cl_cb *cb;
 110	size_t r_length;
 111	ssize_t rets;
 112	bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK);
 113
 114	if (WARN_ON(!cl || !cl->dev))
 115		return -ENODEV;
 116
 117	bus = cl->dev;
 118
 119	mutex_lock(&bus->device_lock);
 120	if (bus->dev_state != MEI_DEV_ENABLED) {
 121		rets = -ENODEV;
 122		goto out;
 123	}
 124
 125	cb = mei_cl_read_cb(cl, NULL);
 126	if (cb)
 127		goto copy;
 128
 129	rets = mei_cl_read_start(cl, length, NULL);
 130	if (rets && rets != -EBUSY)
 131		goto out;
 132
 133	if (nonblock) {
 134		rets = -EAGAIN;
 135		goto out;
 136	}
 137
 138	/* wait on event only if there is no other waiter */
 139	/* synchronized under device mutex */
 140	if (!waitqueue_active(&cl->rx_wait)) {
 141
 142		mutex_unlock(&bus->device_lock);
 143
 144		if (wait_event_interruptible(cl->rx_wait,
 145				(!list_empty(&cl->rd_completed)) ||
 146				(!mei_cl_is_connected(cl)))) {
 147
 148			if (signal_pending(current))
 149				return -EINTR;
 150			return -ERESTARTSYS;
 151		}
 152
 153		mutex_lock(&bus->device_lock);
 154
 155		if (!mei_cl_is_connected(cl)) {
 156			rets = -ENODEV;
 157			goto out;
 158		}
 159	}
 160
 161	cb = mei_cl_read_cb(cl, NULL);
 162	if (!cb) {
 163		rets = 0;
 164		goto out;
 165	}
 166
 167copy:
 168	if (cb->status) {
 169		rets = cb->status;
 170		goto free;
 171	}
 172
 173	r_length = min_t(size_t, length, cb->buf_idx);
 174	memcpy(buf, cb->buf.data, r_length);
 175	rets = r_length;
 176
 177free:
 178	mei_io_cb_free(cb);
 179out:
 180	mutex_unlock(&bus->device_lock);
 181
 182	return rets;
 183}
 184
 185/**
 186 * mei_cldev_send - me device send  (write)
 187 *
 188 * @cldev: me client device
 189 * @buf: buffer to send
 190 * @length: buffer length
 191 *
 192 * Return: written size in bytes or < 0 on error
 193 */
 194ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 195{
 196	struct mei_cl *cl = cldev->cl;
 197
 198	return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
 199}
 200EXPORT_SYMBOL_GPL(mei_cldev_send);
 201
 202/**
 203 * mei_cldev_recv_nonblock - non block client receive (read)
 204 *
 205 * @cldev: me client device
 206 * @buf: buffer to receive
 207 * @length: buffer length
 208 *
 209 * Return: read size in bytes of < 0 on error
 210 *         -EAGAIN if function will block.
 211 */
 212ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
 213				size_t length)
 214{
 215	struct mei_cl *cl = cldev->cl;
 216
 217	return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK);
 218}
 219EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
 220
 221/**
 222 * mei_cldev_recv - client receive (read)
 223 *
 224 * @cldev: me client device
 225 * @buf: buffer to receive
 226 * @length: buffer length
 227 *
 228 * Return: read size in bytes of < 0 on error
 229 */
 230ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
 231{
 232	struct mei_cl *cl = cldev->cl;
 233
 234	return __mei_cl_recv(cl, buf, length, 0);
 235}
 236EXPORT_SYMBOL_GPL(mei_cldev_recv);
 237
 238/**
 239 * mei_cl_bus_rx_work - dispatch rx event for a bus device
 240 *
 241 * @work: work
 242 */
 243static void mei_cl_bus_rx_work(struct work_struct *work)
 244{
 245	struct mei_cl_device *cldev;
 246	struct mei_device *bus;
 247
 248	cldev = container_of(work, struct mei_cl_device, rx_work);
 249
 250	bus = cldev->bus;
 251
 252	if (cldev->rx_cb)
 253		cldev->rx_cb(cldev);
 254
 255	mutex_lock(&bus->device_lock);
 256	mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
 257	mutex_unlock(&bus->device_lock);
 258}
 259
 260/**
 261 * mei_cl_bus_notif_work - dispatch FW notif event for a bus device
 262 *
 263 * @work: work
 264 */
 265static void mei_cl_bus_notif_work(struct work_struct *work)
 266{
 267	struct mei_cl_device *cldev;
 268
 269	cldev = container_of(work, struct mei_cl_device, notif_work);
 270
 271	if (cldev->notif_cb)
 272		cldev->notif_cb(cldev);
 273}
 274
 275/**
 276 * mei_cl_bus_notify_event - schedule notify cb on bus client
 277 *
 278 * @cl: host client
 279 *
 280 * Return: true if event was scheduled
 281 *         false if the client is not waiting for event
 282 */
 283bool mei_cl_bus_notify_event(struct mei_cl *cl)
 284{
 285	struct mei_cl_device *cldev = cl->cldev;
 286
 287	if (!cldev || !cldev->notif_cb)
 288		return false;
 289
 290	if (!cl->notify_ev)
 291		return false;
 292
 293	schedule_work(&cldev->notif_work);
 294
 295	cl->notify_ev = false;
 296
 297	return true;
 298}
 299
 300/**
 301 * mei_cl_bus_rx_event - schedule rx event
 302 *
 303 * @cl: host client
 304 *
 305 * Return: true if event was scheduled
 306 *         false if the client is not waiting for event
 307 */
 308bool mei_cl_bus_rx_event(struct mei_cl *cl)
 309{
 310	struct mei_cl_device *cldev = cl->cldev;
 311
 312	if (!cldev || !cldev->rx_cb)
 313		return false;
 314
 315	schedule_work(&cldev->rx_work);
 316
 317	return true;
 318}
 319
 320/**
 321 * mei_cldev_register_rx_cb - register Rx event callback
 322 *
 323 * @cldev: me client devices
 324 * @rx_cb: callback function
 325 *
 326 * Return: 0 on success
 327 *         -EALREADY if an callback is already registered
 328 *         <0 on other errors
 329 */
 330int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb)
 331{
 332	struct mei_device *bus = cldev->bus;
 333	int ret;
 334
 335	if (!rx_cb)
 336		return -EINVAL;
 337	if (cldev->rx_cb)
 338		return -EALREADY;
 339
 340	cldev->rx_cb = rx_cb;
 341	INIT_WORK(&cldev->rx_work, mei_cl_bus_rx_work);
 342
 343	mutex_lock(&bus->device_lock);
 344	ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
 345	mutex_unlock(&bus->device_lock);
 346	if (ret && ret != -EBUSY)
 347		return ret;
 348
 349	return 0;
 350}
 351EXPORT_SYMBOL_GPL(mei_cldev_register_rx_cb);
 352
 353/**
 354 * mei_cldev_register_notif_cb - register FW notification event callback
 355 *
 356 * @cldev: me client devices
 357 * @notif_cb: callback function
 358 *
 359 * Return: 0 on success
 360 *         -EALREADY if an callback is already registered
 361 *         <0 on other errors
 362 */
 363int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,
 364				mei_cldev_cb_t notif_cb)
 365{
 366	struct mei_device *bus = cldev->bus;
 367	int ret;
 368
 369	if (!notif_cb)
 370		return -EINVAL;
 371
 372	if (cldev->notif_cb)
 373		return -EALREADY;
 374
 375	cldev->notif_cb = notif_cb;
 376	INIT_WORK(&cldev->notif_work, mei_cl_bus_notif_work);
 377
 378	mutex_lock(&bus->device_lock);
 379	ret = mei_cl_notify_request(cldev->cl, NULL, 1);
 380	mutex_unlock(&bus->device_lock);
 381	if (ret)
 382		return ret;
 383
 384	return 0;
 385}
 386EXPORT_SYMBOL_GPL(mei_cldev_register_notif_cb);
 387
 388/**
 389 * mei_cldev_get_drvdata - driver data getter
 390 *
 391 * @cldev: mei client device
 392 *
 393 * Return: driver private data
 394 */
 395void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
 396{
 397	return dev_get_drvdata(&cldev->dev);
 398}
 399EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
 400
 401/**
 402 * mei_cldev_set_drvdata - driver data setter
 403 *
 404 * @cldev: mei client device
 405 * @data: data to store
 406 */
 407void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
 408{
 409	dev_set_drvdata(&cldev->dev, data);
 410}
 411EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
 412
 413/**
 414 * mei_cldev_uuid - return uuid of the underlying me client
 415 *
 416 * @cldev: mei client device
 417 *
 418 * Return: me client uuid
 419 */
 420const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
 421{
 422	return mei_me_cl_uuid(cldev->me_cl);
 423}
 424EXPORT_SYMBOL_GPL(mei_cldev_uuid);
 425
 426/**
 427 * mei_cldev_ver - return protocol version of the underlying me client
 428 *
 429 * @cldev: mei client device
 430 *
 431 * Return: me client protocol version
 432 */
 433u8 mei_cldev_ver(const struct mei_cl_device *cldev)
 434{
 435	return mei_me_cl_ver(cldev->me_cl);
 436}
 437EXPORT_SYMBOL_GPL(mei_cldev_ver);
 438
 439/**
 440 * mei_cldev_enabled - check whether the device is enabled
 441 *
 442 * @cldev: mei client device
 443 *
 444 * Return: true if me client is initialized and connected
 445 */
 446bool mei_cldev_enabled(struct mei_cl_device *cldev)
 447{
 448	return mei_cl_is_connected(cldev->cl);
 449}
 450EXPORT_SYMBOL_GPL(mei_cldev_enabled);
 451
 452/**
 453 * mei_cldev_enable - enable me client device
 454 *     create connection with me client
 455 *
 456 * @cldev: me client device
 457 *
 458 * Return: 0 on success and < 0 on error
 459 */
 460int mei_cldev_enable(struct mei_cl_device *cldev)
 461{
 462	struct mei_device *bus = cldev->bus;
 463	struct mei_cl *cl;
 464	int ret;
 465
 466	cl = cldev->cl;
 467
 468	if (cl->state == MEI_FILE_UNINITIALIZED) {
 469		mutex_lock(&bus->device_lock);
 470		ret = mei_cl_link(cl);
 471		mutex_unlock(&bus->device_lock);
 472		if (ret)
 473			return ret;
 474		/* update pointers */
 475		cl->cldev = cldev;
 476	}
 477
 478	mutex_lock(&bus->device_lock);
 479	if (mei_cl_is_connected(cl)) {
 480		ret = 0;
 481		goto out;
 482	}
 483
 484	if (!mei_me_cl_is_active(cldev->me_cl)) {
 485		dev_err(&cldev->dev, "me client is not active\n");
 486		ret = -ENOTTY;
 487		goto out;
 488	}
 489
 490	ret = mei_cl_connect(cl, cldev->me_cl, NULL);
 491	if (ret < 0)
 492		dev_err(&cldev->dev, "cannot connect\n");
 493
 494out:
 495	mutex_unlock(&bus->device_lock);
 496
 497	return ret;
 498}
 499EXPORT_SYMBOL_GPL(mei_cldev_enable);
 500
 501/**
 502 * mei_cldev_disable - disable me client device
 503 *     disconnect form the me client
 504 *
 505 * @cldev: me client device
 506 *
 507 * Return: 0 on success and < 0 on error
 508 */
 509int mei_cldev_disable(struct mei_cl_device *cldev)
 510{
 511	struct mei_device *bus;
 512	struct mei_cl *cl;
 513	int err;
 514
 515	if (!cldev)
 516		return -ENODEV;
 517
 518	cl = cldev->cl;
 519
 520	bus = cldev->bus;
 521
 522	mutex_lock(&bus->device_lock);
 523
 524	if (!mei_cl_is_connected(cl)) {
 525		dev_dbg(bus->dev, "Already disconnected");
 526		err = 0;
 527		goto out;
 528	}
 529
 530	err = mei_cl_disconnect(cl);
 531	if (err < 0)
 532		dev_err(bus->dev, "Could not disconnect from the ME client");
 533
 534out:
 535	/* Flush queues and remove any pending read */
 536	mei_cl_flush_queues(cl, NULL);
 537	mei_cl_unlink(cl);
 538
 539	mutex_unlock(&bus->device_lock);
 540	return err;
 541}
 542EXPORT_SYMBOL_GPL(mei_cldev_disable);
 543
 544/**
 545 * mei_cl_device_find - find matching entry in the driver id table
 546 *
 547 * @cldev: me client device
 548 * @cldrv: me client driver
 549 *
 550 * Return: id on success; NULL if no id is matching
 551 */
 552static const
 553struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
 554					    struct mei_cl_driver *cldrv)
 555{
 556	const struct mei_cl_device_id *id;
 557	const uuid_le *uuid;
 558	u8 version;
 559	bool match;
 560
 561	uuid = mei_me_cl_uuid(cldev->me_cl);
 562	version = mei_me_cl_ver(cldev->me_cl);
 563
 564	id = cldrv->id_table;
 565	while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
 566		if (!uuid_le_cmp(*uuid, id->uuid)) {
 567			match = true;
 568
 569			if (cldev->name[0])
 570				if (strncmp(cldev->name, id->name,
 571					    sizeof(id->name)))
 572					match = false;
 573
 574			if (id->version != MEI_CL_VERSION_ANY)
 575				if (id->version != version)
 576					match = false;
 577			if (match)
 578				return id;
 579		}
 580
 581		id++;
 582	}
 583
 584	return NULL;
 585}
 586
 587/**
 588 * mei_cl_device_match  - device match function
 589 *
 590 * @dev: device
 591 * @drv: driver
 592 *
 593 * Return:  1 if matching device was found 0 otherwise
 594 */
 595static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
 596{
 597	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 598	struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
 599	const struct mei_cl_device_id *found_id;
 600
 601	if (!cldev)
 602		return 0;
 603
 604	if (!cldev->do_match)
 605		return 0;
 606
 607	if (!cldrv || !cldrv->id_table)
 608		return 0;
 609
 610	found_id = mei_cl_device_find(cldev, cldrv);
 611	if (found_id)
 612		return 1;
 613
 614	return 0;
 615}
 616
 617/**
 618 * mei_cl_device_probe - bus probe function
 619 *
 620 * @dev: device
 621 *
 622 * Return:  0 on success; < 0 otherwise
 623 */
 624static int mei_cl_device_probe(struct device *dev)
 625{
 626	struct mei_cl_device *cldev;
 627	struct mei_cl_driver *cldrv;
 628	const struct mei_cl_device_id *id;
 629	int ret;
 630
 631	cldev = to_mei_cl_device(dev);
 632	cldrv = to_mei_cl_driver(dev->driver);
 633
 634	if (!cldev)
 635		return 0;
 636
 637	if (!cldrv || !cldrv->probe)
 638		return -ENODEV;
 639
 640	id = mei_cl_device_find(cldev, cldrv);
 641	if (!id)
 642		return -ENODEV;
 643
 644	ret = cldrv->probe(cldev, id);
 645	if (ret)
 646		return ret;
 647
 648	__module_get(THIS_MODULE);
 649	return 0;
 650}
 651
 652/**
 653 * mei_cl_device_remove - remove device from the bus
 654 *
 655 * @dev: device
 656 *
 657 * Return:  0 on success; < 0 otherwise
 658 */
 659static int mei_cl_device_remove(struct device *dev)
 660{
 661	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 662	struct mei_cl_driver *cldrv;
 663	int ret = 0;
 664
 665	if (!cldev || !dev->driver)
 666		return 0;
 667
 668	if (cldev->rx_cb) {
 669		cancel_work_sync(&cldev->rx_work);
 670		cldev->rx_cb = NULL;
 671	}
 672	if (cldev->notif_cb) {
 673		cancel_work_sync(&cldev->notif_work);
 674		cldev->notif_cb = NULL;
 675	}
 676
 677	cldrv = to_mei_cl_driver(dev->driver);
 678	if (cldrv->remove)
 679		ret = cldrv->remove(cldev);
 680
 681	module_put(THIS_MODULE);
 682	dev->driver = NULL;
 683	return ret;
 684
 685}
 686
 687static ssize_t name_show(struct device *dev, struct device_attribute *a,
 688			     char *buf)
 689{
 690	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 691
 692	return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
 693}
 694static DEVICE_ATTR_RO(name);
 695
 696static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
 697			     char *buf)
 698{
 699	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 700	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 701
 702	return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
 703}
 704static DEVICE_ATTR_RO(uuid);
 705
 706static ssize_t version_show(struct device *dev, struct device_attribute *a,
 707			     char *buf)
 708{
 709	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 710	u8 version = mei_me_cl_ver(cldev->me_cl);
 711
 712	return scnprintf(buf, PAGE_SIZE, "%02X", version);
 713}
 714static DEVICE_ATTR_RO(version);
 715
 716static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 717			     char *buf)
 718{
 719	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 720	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 721
 722	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
 723}
 724static DEVICE_ATTR_RO(modalias);
 725
 726static struct attribute *mei_cldev_attrs[] = {
 727	&dev_attr_name.attr,
 728	&dev_attr_uuid.attr,
 729	&dev_attr_version.attr,
 730	&dev_attr_modalias.attr,
 731	NULL,
 732};
 733ATTRIBUTE_GROUPS(mei_cldev);
 734
 735/**
 736 * mei_cl_device_uevent - me client bus uevent handler
 737 *
 738 * @dev: device
 739 * @env: uevent kobject
 740 *
 741 * Return: 0 on success -ENOMEM on when add_uevent_var fails
 742 */
 743static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 744{
 745	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 746	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 747	u8 version = mei_me_cl_ver(cldev->me_cl);
 748
 749	if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
 750		return -ENOMEM;
 751
 752	if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
 753		return -ENOMEM;
 754
 755	if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
 756		return -ENOMEM;
 757
 758	if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
 759			   cldev->name, uuid, version))
 760		return -ENOMEM;
 761
 762	return 0;
 763}
 764
 765static struct bus_type mei_cl_bus_type = {
 766	.name		= "mei",
 767	.dev_groups	= mei_cldev_groups,
 768	.match		= mei_cl_device_match,
 769	.probe		= mei_cl_device_probe,
 770	.remove		= mei_cl_device_remove,
 771	.uevent		= mei_cl_device_uevent,
 772};
 773
 774static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
 775{
 776	if (bus)
 777		get_device(bus->dev);
 778
 779	return bus;
 780}
 781
 782static void mei_dev_bus_put(struct mei_device *bus)
 783{
 784	if (bus)
 785		put_device(bus->dev);
 786}
 787
 788static void mei_cl_bus_dev_release(struct device *dev)
 789{
 790	struct mei_cl_device *cldev = to_mei_cl_device(dev);
 791
 792	if (!cldev)
 793		return;
 794
 795	mei_me_cl_put(cldev->me_cl);
 796	mei_dev_bus_put(cldev->bus);
 797	kfree(cldev->cl);
 798	kfree(cldev);
 799}
 800
 801static struct device_type mei_cl_device_type = {
 802	.release	= mei_cl_bus_dev_release,
 803};
 804
 805/**
 806 * mei_cl_bus_set_name - set device name for me client device
 807 *
 808 * @cldev: me client device
 809 */
 810static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
 811{
 812	dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X",
 813		     cldev->name,
 814		     mei_me_cl_uuid(cldev->me_cl),
 815		     mei_me_cl_ver(cldev->me_cl));
 816}
 817
 818/**
 819 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
 820 *
 821 * @bus: mei device
 822 * @me_cl: me client
 823 *
 824 * Return: allocated device structur or NULL on allocation failure
 825 */
 826static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
 827						  struct mei_me_client *me_cl)
 828{
 829	struct mei_cl_device *cldev;
 830	struct mei_cl *cl;
 831
 832	cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
 833	if (!cldev)
 834		return NULL;
 835
 836	cl = mei_cl_allocate(bus);
 837	if (!cl) {
 838		kfree(cldev);
 839		return NULL;
 840	}
 841
 842	device_initialize(&cldev->dev);
 843	cldev->dev.parent = bus->dev;
 844	cldev->dev.bus    = &mei_cl_bus_type;
 845	cldev->dev.type   = &mei_cl_device_type;
 846	cldev->bus        = mei_dev_bus_get(bus);
 847	cldev->me_cl      = mei_me_cl_get(me_cl);
 848	cldev->cl         = cl;
 849	mei_cl_bus_set_name(cldev);
 850	cldev->is_added   = 0;
 851	INIT_LIST_HEAD(&cldev->bus_list);
 852
 853	return cldev;
 854}
 855
 856/**
 857 * mei_cl_dev_setup - setup me client device
 858 *    run fix up routines and set the device name
 859 *
 860 * @bus: mei device
 861 * @cldev: me client device
 862 *
 863 * Return: true if the device is eligible for enumeration
 864 */
 865static bool mei_cl_bus_dev_setup(struct mei_device *bus,
 866				 struct mei_cl_device *cldev)
 867{
 868	cldev->do_match = 1;
 869	mei_cl_bus_dev_fixup(cldev);
 870
 871	/* the device name can change during fix up */
 872	if (cldev->do_match)
 873		mei_cl_bus_set_name(cldev);
 874
 875	return cldev->do_match == 1;
 876}
 877
 878/**
 879 * mei_cl_bus_dev_add - add me client devices
 880 *
 881 * @cldev: me client device
 882 *
 883 * Return: 0 on success; < 0 on failre
 884 */
 885static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
 886{
 887	int ret;
 888
 889	dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
 890		mei_me_cl_uuid(cldev->me_cl),
 891		mei_me_cl_ver(cldev->me_cl));
 892	ret = device_add(&cldev->dev);
 893	if (!ret)
 894		cldev->is_added = 1;
 895
 896	return ret;
 897}
 898
 899/**
 900 * mei_cl_bus_dev_stop - stop the driver
 901 *
 902 * @cldev: me client device
 903 */
 904static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
 905{
 906	if (cldev->is_added)
 907		device_release_driver(&cldev->dev);
 908}
 909
 910/**
 911 * mei_cl_bus_dev_destroy - destroy me client devices object
 912 *
 913 * @cldev: me client device
 914 *
 915 * Locking: called under "dev->cl_bus_lock" lock
 916 */
 917static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
 918{
 919
 920	WARN_ON(!mutex_is_locked(&cldev->bus->cl_bus_lock));
 921
 922	if (!cldev->is_added)
 923		return;
 924
 925	device_del(&cldev->dev);
 926
 927	list_del_init(&cldev->bus_list);
 928
 929	cldev->is_added = 0;
 930	put_device(&cldev->dev);
 931}
 932
 933/**
 934 * mei_cl_bus_remove_device - remove a devices form the bus
 935 *
 936 * @cldev: me client device
 937 */
 938static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
 939{
 940	mei_cl_bus_dev_stop(cldev);
 941	mei_cl_bus_dev_destroy(cldev);
 942}
 943
 944/**
 945 * mei_cl_bus_remove_devices - remove all devices form the bus
 946 *
 947 * @bus: mei device
 948 */
 949void mei_cl_bus_remove_devices(struct mei_device *bus)
 950{
 951	struct mei_cl_device *cldev, *next;
 952
 953	mutex_lock(&bus->cl_bus_lock);
 954	list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
 955		mei_cl_bus_remove_device(cldev);
 956	mutex_unlock(&bus->cl_bus_lock);
 957}
 958
 959
 960/**
 961 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
 962 *     based on me client
 963 *
 964 * @bus: mei device
 965 * @me_cl: me client
 966 *
 967 * Locking: called under "dev->cl_bus_lock" lock
 968 */
 969static void mei_cl_bus_dev_init(struct mei_device *bus,
 970				struct mei_me_client *me_cl)
 971{
 972	struct mei_cl_device *cldev;
 973
 974	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));
 975
 976	dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
 977
 978	if (me_cl->bus_added)
 979		return;
 980
 981	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
 982	if (!cldev)
 983		return;
 984
 985	me_cl->bus_added = true;
 986	list_add_tail(&cldev->bus_list, &bus->device_list);
 987
 988}
 989
 990/**
 991 * mei_cl_bus_rescan - scan me clients list and add create
 992 *    devices for eligible clients
 993 *
 994 * @bus: mei device
 995 */
 996void mei_cl_bus_rescan(struct mei_device *bus)
 997{
 998	struct mei_cl_device *cldev, *n;
 999	struct mei_me_client *me_cl;
1000
1001	mutex_lock(&bus->cl_bus_lock);
1002
1003	down_read(&bus->me_clients_rwsem);
1004	list_for_each_entry(me_cl, &bus->me_clients, list)
1005		mei_cl_bus_dev_init(bus, me_cl);
1006	up_read(&bus->me_clients_rwsem);
1007
1008	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
1009
1010		if (!mei_me_cl_is_active(cldev->me_cl)) {
1011			mei_cl_bus_remove_device(cldev);
1012			continue;
1013		}
1014
1015		if (cldev->is_added)
1016			continue;
1017
1018		if (mei_cl_bus_dev_setup(bus, cldev))
1019			mei_cl_bus_dev_add(cldev);
1020		else {
1021			list_del_init(&cldev->bus_list);
1022			put_device(&cldev->dev);
1023		}
1024	}
1025	mutex_unlock(&bus->cl_bus_lock);
1026
1027	dev_dbg(bus->dev, "rescan end");
1028}
1029
1030void mei_cl_bus_rescan_work(struct work_struct *work)
1031{
1032	struct mei_device *bus =
1033		container_of(work, struct mei_device, bus_rescan_work);
1034	struct mei_me_client *me_cl;
1035
1036	me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
1037	if (me_cl)
1038		mei_amthif_host_init(bus, me_cl);
1039	mei_me_cl_put(me_cl);
1040
1041	mei_cl_bus_rescan(bus);
1042}
1043
1044int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
1045				struct module *owner)
1046{
1047	int err;
1048
1049	cldrv->driver.name = cldrv->name;
1050	cldrv->driver.owner = owner;
1051	cldrv->driver.bus = &mei_cl_bus_type;
1052
1053	err = driver_register(&cldrv->driver);
1054	if (err)
1055		return err;
1056
1057	pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
1058
1059	return 0;
1060}
1061EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1062
1063void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1064{
1065	driver_unregister(&cldrv->driver);
1066
1067	pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1068}
1069EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1070
1071
1072int __init mei_cl_bus_init(void)
1073{
1074	return bus_register(&mei_cl_bus_type);
1075}
1076
1077void __exit mei_cl_bus_exit(void)
1078{
1079	bus_unregister(&mei_cl_bus_type);
1080}