bus.c 20.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Intel Management Engine Interface (Intel MEI) Linux driver
 * Copyright (c) 2012-2013, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
19
#include <linux/sched.h>
20 21 22 23 24 25 26 27
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/mei_cl_bus.h>

#include "mei_dev.h"
28
#include "client.h"
29 30 31 32

#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)

33 34 35 36 37 38 39 40 41 42 43 44
/**
 * __mei_cl_send - internal client send (write)
 *
 * @cl: host client
 * @buf: buffer to send
 * @length: buffer length
 * @blocking: wait for write completion
 *
 * Return: written size bytes or < 0 on error
 */
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
			bool blocking)
45
{
46
	struct mei_device *bus;
47
	struct mei_cl_cb *cb;
48
	ssize_t rets;
49

50 51
	if (WARN_ON(!cl || !cl->dev))
		return -ENODEV;
52

53
	bus = cl->dev;
54

55
	mutex_lock(&bus->device_lock);
56 57 58 59 60
	if (bus->dev_state != MEI_DEV_ENABLED) {
		rets = -ENODEV;
		goto out;
	}

61 62 63 64
	if (!mei_cl_is_connected(cl)) {
		rets = -ENODEV;
		goto out;
	}
65

66 67 68 69 70
	/* Check if we have an ME client device */
	if (!mei_me_cl_is_active(cl->me_cl)) {
		rets = -ENOTTY;
		goto out;
	}
71

72 73 74 75
	if (length > mei_cl_mtu(cl)) {
		rets = -EFBIG;
		goto out;
	}
76

77 78 79 80
	cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
	if (!cb) {
		rets = -ENOMEM;
		goto out;
81 82
	}

83 84 85 86 87 88 89 90
	memcpy(cb->buf.data, buf, length);

	rets = mei_cl_write(cl, cb, blocking);

out:
	mutex_unlock(&bus->device_lock);

	return rets;
91 92
}

93 94 95 96
/**
 * __mei_cl_recv - internal client receive (read)
 *
 * @cl: host client
97
 * @buf: buffer to receive
98 99 100 101 102
 * @length: buffer length
 *
 * Return: read size in bytes of < 0 on error
 */
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
103
{
104 105 106 107
	struct mei_device *bus;
	struct mei_cl_cb *cb;
	size_t r_length;
	ssize_t rets;
108

109
	if (WARN_ON(!cl || !cl->dev))
110 111
		return -ENODEV;

112
	bus = cl->dev;
113

114
	mutex_lock(&bus->device_lock);
115 116 117 118
	if (bus->dev_state != MEI_DEV_ENABLED) {
		rets = -ENODEV;
		goto out;
	}
119

120 121 122
	cb = mei_cl_read_cb(cl, NULL);
	if (cb)
		goto copy;
123

124 125 126
	rets = mei_cl_read_start(cl, length, NULL);
	if (rets && rets != -EBUSY)
		goto out;
127

128 129
	/* wait on event only if there is no other waiter */
	if (list_empty(&cl->rd_completed) && !waitqueue_active(&cl->rx_wait)) {
130

131
		mutex_unlock(&bus->device_lock);
132

133 134 135
		if (wait_event_interruptible(cl->rx_wait,
				(!list_empty(&cl->rd_completed)) ||
				(!mei_cl_is_connected(cl)))) {
136

137 138 139 140 141 142 143 144 145 146 147
			if (signal_pending(current))
				return -EINTR;
			return -ERESTARTSYS;
		}

		mutex_lock(&bus->device_lock);

		if (!mei_cl_is_connected(cl)) {
			rets = -EBUSY;
			goto out;
		}
148 149
	}

150 151 152 153 154
	cb = mei_cl_read_cb(cl, NULL);
	if (!cb) {
		rets = 0;
		goto out;
	}
155

156 157 158 159 160
copy:
	if (cb->status) {
		rets = cb->status;
		goto free;
	}
161

162 163 164
	r_length = min_t(size_t, length, cb->buf_idx);
	memcpy(buf, cb->buf.data, r_length);
	rets = r_length;
165

166 167 168 169 170 171
free:
	mei_io_cb_free(cb);
out:
	mutex_unlock(&bus->device_lock);

	return rets;
172 173
}

174
/**
175
 * mei_cldev_send - me device send  (write)
176 177 178 179 180 181 182
 *
 * @cldev: me client device
 * @buf: buffer to send
 * @length: buffer length
 *
 * Return: written size in bytes or < 0 on error
 */
183
ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
184
{
185
	struct mei_cl *cl = cldev->cl;
186

187 188
	if (cl == NULL)
		return -ENODEV;
189

190
	return __mei_cl_send(cl, buf, length, 1);
191
}
192
EXPORT_SYMBOL_GPL(mei_cldev_send);
193

194
/**
195
 * mei_cldev_recv - client receive (read)
196 197
 *
 * @cldev: me client device
198
 * @buf: buffer to receive
199 200 201 202
 * @length: buffer length
 *
 * Return: read size in bytes of < 0 on error
 */
203
ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
204
{
205
	struct mei_cl *cl = cldev->cl;
206

207 208
	if (cl == NULL)
		return -ENODEV;
209

210
	return __mei_cl_recv(cl, buf, length);
211
}
212
EXPORT_SYMBOL_GPL(mei_cldev_recv);
213

214
/**
215
 * mei_cl_bus_event_work  - dispatch rx event for a bus device
216 217 218 219
 *    and schedule new work
 *
 * @work: work
 */
220
static void mei_cl_bus_event_work(struct work_struct *work)
221
{
222
	struct mei_cl_device *cldev;
223

224
	cldev = container_of(work, struct mei_cl_device, event_work);
225

226 227
	if (cldev->event_cb)
		cldev->event_cb(cldev, cldev->events, cldev->event_context);
228

229
	cldev->events = 0;
230

231
	/* Prepare for the next read */
232 233 234 235 236 237 238 239
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX))
		mei_cl_read_start(cldev->cl, 0, NULL);
}

/**
 * mei_cl_bus_notify_event - schedule notify cb on bus client
 *
 * @cl: host client
240 241 242
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
243
 */
244
bool mei_cl_bus_notify_event(struct mei_cl *cl)
245 246 247 248
{
	struct mei_cl_device *cldev = cl->cldev;

	if (!cldev || !cldev->event_cb)
249
		return false;
250 251

	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
252
		return false;
253 254

	if (!cl->notify_ev)
255
		return false;
256 257 258 259 260 261

	set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);

	schedule_work(&cldev->event_work);

	cl->notify_ev = false;
262 263

	return true;
264 265
}

266
/**
267
 * mei_cl_bus_rx_event  - schedule rx event
268 269
 *
 * @cl: host client
270 271 272
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
273
 */
274
bool mei_cl_bus_rx_event(struct mei_cl *cl)
275
{
276
	struct mei_cl_device *cldev = cl->cldev;
277

278
	if (!cldev || !cldev->event_cb)
279
		return false;
280

281
	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX)))
282
		return false;
283

284
	set_bit(MEI_CL_EVENT_RX, &cldev->events);
285

286
	schedule_work(&cldev->event_work);
287 288

	return true;
289
}
290

291
/**
292
 * mei_cldev_register_event_cb - register event callback
293 294 295
 *
 * @cldev: me client devices
 * @event_cb: callback function
296
 * @events_mask: requested events bitmask
297 298 299 300 301 302
 * @context: driver context data
 *
 * Return: 0 on success
 *         -EALREADY if an callback is already registered
 *         <0 on other errors
 */
303 304 305
int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
				unsigned long events_mask,
				mei_cldev_event_cb_t event_cb, void *context)
306
{
307 308
	int ret;

309 310
	if (cldev->event_cb)
		return -EALREADY;
311

312
	cldev->events = 0;
313
	cldev->events_mask = events_mask;
314 315
	cldev->event_cb = event_cb;
	cldev->event_context = context;
316
	INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
317

318 319 320 321 322 323 324 325 326 327 328 329 330
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
		ret = mei_cl_read_start(cldev->cl, 0, NULL);
		if (ret && ret != -EBUSY)
			return ret;
	}

	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
		mutex_lock(&cldev->cl->dev->device_lock);
		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
		mutex_unlock(&cldev->cl->dev->device_lock);
		if (ret)
			return ret;
	}
331

332 333
	return 0;
}
334
EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
335

336
/**
337
 * mei_cldev_get_drvdata - driver data getter
338 339 340 341 342
 *
 * @cldev: mei client device
 *
 * Return: driver private data
 */
343
void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
344 345
{
	return dev_get_drvdata(&cldev->dev);
346
}
347
EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
348

349
/**
350
 * mei_cldev_set_drvdata - driver data setter
351 352 353 354
 *
 * @cldev: mei client device
 * @data: data to store
 */
355
void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
356
{
357
	dev_set_drvdata(&cldev->dev, data);
358
}
359
EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
360

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
/**
 * mei_cldev_uuid - return uuid of the underlying me client
 *
 * @cldev: mei client device
 *
 * Return: me client uuid
 */
const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
{
	return mei_me_cl_uuid(cldev->me_cl);
}
EXPORT_SYMBOL_GPL(mei_cldev_uuid);

/**
 * mei_cldev_ver - return protocol version of the underlying me client
 *
 * @cldev: mei client device
 *
 * Return: me client protocol version
 */
u8 mei_cldev_ver(const struct mei_cl_device *cldev)
{
	return mei_me_cl_ver(cldev->me_cl);
}
EXPORT_SYMBOL_GPL(mei_cldev_ver);

387 388 389 390 391 392 393 394 395 396 397 398 399
/**
 * mei_cldev_enabled - check whether the device is enabled
 *
 * @cldev: mei client device
 *
 * Return: true if me client is initialized and connected
 */
bool mei_cldev_enabled(struct mei_cl_device *cldev)
{
	return cldev->cl && mei_cl_is_connected(cldev->cl);
}
EXPORT_SYMBOL_GPL(mei_cldev_enabled);

400
/**
401
 * mei_cldev_enable_device - enable me client device
402 403 404 405 406 407
 *     create connection with me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
408
int mei_cldev_enable(struct mei_cl_device *cldev)
409
{
410 411 412
	struct mei_device *bus = cldev->bus;
	struct mei_cl *cl;
	int ret;
413

414
	cl = cldev->cl;
415

416 417
	if (!cl) {
		mutex_lock(&bus->device_lock);
418
		cl = mei_cl_alloc_linked(bus);
419 420 421 422 423 424 425
		mutex_unlock(&bus->device_lock);
		if (IS_ERR(cl))
			return PTR_ERR(cl);
		/* update pointers */
		cldev->cl = cl;
		cl->cldev = cldev;
	}
426

427 428
	mutex_lock(&bus->device_lock);
	if (mei_cl_is_connected(cl)) {
429 430
		ret = 0;
		goto out;
431
	}
432

433 434 435 436
	if (!mei_me_cl_is_active(cldev->me_cl)) {
		dev_err(&cldev->dev, "me client is not active\n");
		ret = -ENOTTY;
		goto out;
437 438
	}

439 440 441 442 443
	ret = mei_cl_connect(cl, cldev->me_cl, NULL);
	if (ret < 0)
		dev_err(&cldev->dev, "cannot connect\n");

out:
444 445
	mutex_unlock(&bus->device_lock);

446
	return ret;
447
}
448
EXPORT_SYMBOL_GPL(mei_cldev_enable);
449

450
/**
451
 * mei_cldev_disable - disable me client device
452 453 454 455 456 457
 *     disconnect form the me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
458
int mei_cldev_disable(struct mei_cl_device *cldev)
459
{
460
	struct mei_device *bus;
461 462
	struct mei_cl *cl;
	int err;
463

464
	if (!cldev || !cldev->cl)
465 466
		return -ENODEV;

467 468 469
	cl = cldev->cl;

	bus = cldev->bus;
T
Tomas Winkler 已提交
470

471
	cldev->event_cb = NULL;
472

473
	mutex_lock(&bus->device_lock);
T
Tomas Winkler 已提交
474

475 476 477
	if (!mei_cl_is_connected(cl)) {
		dev_err(bus->dev, "Already disconnected");
		err = 0;
478 479
		goto out;
	}
T
Tomas Winkler 已提交
480

481
	err = mei_cl_disconnect(cl);
482
	if (err < 0)
483
		dev_err(bus->dev, "Could not disconnect from the ME client");
484

485
out:
486 487
	/* Flush queues and remove any pending read */
	mei_cl_flush_queues(cl, NULL);
488 489 490 491
	mei_cl_unlink(cl);

	kfree(cl);
	cldev->cl = NULL;
492

493
	mutex_unlock(&bus->device_lock);
494
	return err;
495
}
496
EXPORT_SYMBOL_GPL(mei_cldev_disable);
497

T
Tomas Winkler 已提交
498 499 500 501 502 503 504 505 506 507 508
/**
 * mei_cl_device_find - find matching entry in the driver id table
 *
 * @cldev: me client device
 * @cldrv: me client driver
 *
 * Return: id on success; NULL if no id is matching
 */
static const
struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
					    struct mei_cl_driver *cldrv)
509
{
510 511
	const struct mei_cl_device_id *id;
	const uuid_le *uuid;
512 513
	u8 version;
	bool match;
514

515
	uuid = mei_me_cl_uuid(cldev->me_cl);
516
	version = mei_me_cl_ver(cldev->me_cl);
517

518 519 520
	id = cldrv->id_table;
	while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
		if (!uuid_le_cmp(*uuid, id->uuid)) {
521
			match = true;
T
Tomas Winkler 已提交
522

523 524 525 526
			if (cldev->name[0])
				if (strncmp(cldev->name, id->name,
					    sizeof(id->name)))
					match = false;
T
Tomas Winkler 已提交
527

528 529 530 531
			if (id->version != MEI_CL_VERSION_ANY)
				if (id->version != version)
					match = false;
			if (match)
T
Tomas Winkler 已提交
532
				return id;
533
		}
534

535 536
		id++;
	}
537

T
Tomas Winkler 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
	return NULL;
}

/**
 * mei_cl_device_match  - device match function
 *
 * @dev: device
 * @drv: driver
 *
 * Return:  1 if matching device was found 0 otherwise
 */
static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
	const struct mei_cl_device_id *found_id;

	if (!cldev)
		return 0;

558 559 560
	if (!cldev->do_match)
		return 0;

T
Tomas Winkler 已提交
561 562 563 564 565 566 567
	if (!cldrv || !cldrv->id_table)
		return 0;

	found_id = mei_cl_device_find(cldev, cldrv);
	if (found_id)
		return 1;

568 569
	return 0;
}
570

571 572 573 574 575 576 577
/**
 * mei_cl_device_probe - bus probe function
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
578 579
static int mei_cl_device_probe(struct device *dev)
{
580
	struct mei_cl_device *cldev;
581
	struct mei_cl_driver *cldrv;
582 583 584 585
	const struct mei_cl_device_id *id;

	cldev = to_mei_cl_device(dev);
	cldrv = to_mei_cl_driver(dev->driver);
586

587 588
	if (!cldev)
		return 0;
589

590 591 592
	if (!cldrv || !cldrv->probe)
		return -ENODEV;

593 594 595
	id = mei_cl_device_find(cldev, cldrv);
	if (!id)
		return -ENODEV;
596

597
	__module_get(THIS_MODULE);
598

599
	return cldrv->probe(cldev, id);
600
}
601

602 603 604 605 606 607 608
/**
 * mei_cl_device_remove - remove device from the bus
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
609 610 611 612
static int mei_cl_device_remove(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct mei_cl_driver *cldrv;
613
	int ret = 0;
614

615 616 617 618 619 620
	if (!cldev || !dev->driver)
		return 0;

	if (cldev->event_cb) {
		cldev->event_cb = NULL;
		cancel_work_sync(&cldev->event_work);
621 622
	}

623
	cldrv = to_mei_cl_driver(dev->driver);
624 625
	if (cldrv->remove)
		ret = cldrv->remove(cldev);
626

627 628 629
	module_put(THIS_MODULE);
	dev->driver = NULL;
	return ret;
630 631 632

}

633 634
static ssize_t name_show(struct device *dev, struct device_attribute *a,
			     char *buf)
635
{
636
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
637

638
	return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
639
}
640
static DEVICE_ATTR_RO(name);
641

642 643
static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
			     char *buf)
644
{
645 646
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
647

648
	return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
649
}
650
static DEVICE_ATTR_RO(uuid);
651

652 653 654 655 656 657
static ssize_t version_show(struct device *dev, struct device_attribute *a,
			     char *buf)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	u8 version = mei_me_cl_ver(cldev->me_cl);

658
	return scnprintf(buf, PAGE_SIZE, "%02X", version);
659 660 661
}
static DEVICE_ATTR_RO(version);

662 663
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
664
{
665 666
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
667

668
	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
669
}
670
static DEVICE_ATTR_RO(modalias);
671

672
static struct attribute *mei_cldev_attrs[] = {
673 674
	&dev_attr_name.attr,
	&dev_attr_uuid.attr,
675
	&dev_attr_version.attr,
676 677 678
	&dev_attr_modalias.attr,
	NULL,
};
679
ATTRIBUTE_GROUPS(mei_cldev);
680

681 682 683 684 685 686 687 688 689
/**
 * mei_cl_device_uevent - me client bus uevent handler
 *
 * @dev: device
 * @env: uevent kobject
 *
 * Return: 0 on success -ENOMEM on when add_uevent_var fails
 */
static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
690
{
691 692
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
693 694 695 696
	u8 version = mei_me_cl_ver(cldev->me_cl);

	if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
		return -ENOMEM;
697

698 699
	if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
		return -ENOMEM;
700

701 702 703
	if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
		return -ENOMEM;

704 705
	if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
			   cldev->name, uuid, version))
706
		return -ENOMEM;
707 708 709

	return 0;
}
710

711 712
static struct bus_type mei_cl_bus_type = {
	.name		= "mei",
713
	.dev_groups	= mei_cldev_groups,
714 715 716
	.match		= mei_cl_device_match,
	.probe		= mei_cl_device_probe,
	.remove		= mei_cl_device_remove,
717
	.uevent		= mei_cl_device_uevent,
718 719
};

720 721 722 723 724 725 726 727 728 729 730 731 732 733
static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
{
	if (bus)
		get_device(bus->dev);

	return bus;
}

static void mei_dev_bus_put(struct mei_device *bus)
{
	if (bus)
		put_device(bus->dev);
}

734
static void mei_cl_bus_dev_release(struct device *dev)
735
{
736 737 738 739 740 741
	struct mei_cl_device *cldev = to_mei_cl_device(dev);

	if (!cldev)
		return;

	mei_me_cl_put(cldev->me_cl);
742
	mei_dev_bus_put(cldev->bus);
743
	kfree(cldev);
744 745
}

746
static struct device_type mei_cl_device_type = {
747
	.release	= mei_cl_bus_dev_release,
748 749
};

750 751 752 753 754 755 756 757 758 759 760 761 762
/**
 * mei_cl_bus_set_name - set device name for me client device
 *
 * @cldev: me client device
 */
static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
{
	dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X",
		     cldev->name,
		     mei_me_cl_uuid(cldev->me_cl),
		     mei_me_cl_ver(cldev->me_cl));
}

763
/**
764
 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
765 766 767 768 769 770
 *
 * @bus: mei device
 * @me_cl: me client
 *
 * Return: allocated device structur or NULL on allocation failure
 */
771 772
static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
						  struct mei_me_client *me_cl)
773 774 775 776 777 778 779 780 781 782 783 784 785
{
	struct mei_cl_device *cldev;

	cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
	if (!cldev)
		return NULL;

	device_initialize(&cldev->dev);
	cldev->dev.parent = bus->dev;
	cldev->dev.bus    = &mei_cl_bus_type;
	cldev->dev.type   = &mei_cl_device_type;
	cldev->bus        = mei_dev_bus_get(bus);
	cldev->me_cl      = mei_me_cl_get(me_cl);
786
	mei_cl_bus_set_name(cldev);
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
	cldev->is_added   = 0;
	INIT_LIST_HEAD(&cldev->bus_list);

	return cldev;
}

/**
 * mei_cl_dev_setup - setup me client device
 *    run fix up routines and set the device name
 *
 * @bus: mei device
 * @cldev: me client device
 *
 * Return: true if the device is eligible for enumeration
 */
802 803
static bool mei_cl_bus_dev_setup(struct mei_device *bus,
				 struct mei_cl_device *cldev)
804 805
{
	cldev->do_match = 1;
806
	mei_cl_bus_dev_fixup(cldev);
807

808
	/* the device name can change during fix up */
809
	if (cldev->do_match)
810
		mei_cl_bus_set_name(cldev);
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825

	return cldev->do_match == 1;
}

/**
 * mei_cl_bus_dev_add - add me client devices
 *
 * @cldev: me client device
 *
 * Return: 0 on success; < 0 on failre
 */
static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
{
	int ret;

826 827 828
	dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
		mei_me_cl_uuid(cldev->me_cl),
		mei_me_cl_ver(cldev->me_cl));
829 830 831 832 833 834 835
	ret = device_add(&cldev->dev);
	if (!ret)
		cldev->is_added = 1;

	return ret;
}

836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
/**
 * mei_cl_bus_dev_stop - stop the driver
 *
 * @cldev: me client device
 */
static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
{
	if (cldev->is_added)
		device_release_driver(&cldev->dev);
}

/**
 * mei_cl_bus_dev_destroy - destroy me client devices object
 *
 * @cldev: me client device
851 852
 *
 * Locking: called under "dev->cl_bus_lock" lock
853 854 855
 */
static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
{
856 857 858

	WARN_ON(!mutex_is_locked(&cldev->bus->cl_bus_lock));

859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
	if (!cldev->is_added)
		return;

	device_del(&cldev->dev);

	list_del_init(&cldev->bus_list);

	cldev->is_added = 0;
	put_device(&cldev->dev);
}

/**
 * mei_cl_bus_remove_device - remove a devices form the bus
 *
 * @cldev: me client device
 */
static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
{
	mei_cl_bus_dev_stop(cldev);
	mei_cl_bus_dev_destroy(cldev);
}

/**
 * mei_cl_bus_remove_devices - remove all devices form the bus
 *
 * @bus: mei device
 */
void mei_cl_bus_remove_devices(struct mei_device *bus)
{
	struct mei_cl_device *cldev, *next;

890
	mutex_lock(&bus->cl_bus_lock);
891 892
	list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
		mei_cl_bus_remove_device(cldev);
893
	mutex_unlock(&bus->cl_bus_lock);
894 895 896 897
}


/**
898
 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
899 900 901 902
 *     based on me client
 *
 * @bus: mei device
 * @me_cl: me client
903 904
 *
 * Locking: called under "dev->cl_bus_lock" lock
905
 */
906 907
static void mei_cl_bus_dev_init(struct mei_device *bus,
				struct mei_me_client *me_cl)
908
{
909
	struct mei_cl_device *cldev;
910

911 912
	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));

913 914 915 916
	dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));

	if (me_cl->bus_added)
		return;
917

918
	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
919
	if (!cldev)
920
		return;
921

922 923
	me_cl->bus_added = true;
	list_add_tail(&cldev->bus_list, &bus->device_list);
T
Tomas Winkler 已提交
924

925
}
926

927 928 929 930 931 932 933 934 935 936
/**
 * mei_cl_bus_rescan - scan me clients list and add create
 *    devices for eligible clients
 *
 * @bus: mei device
 */
void mei_cl_bus_rescan(struct mei_device *bus)
{
	struct mei_cl_device *cldev, *n;
	struct mei_me_client *me_cl;
937

938 939
	mutex_lock(&bus->cl_bus_lock);

940 941
	down_read(&bus->me_clients_rwsem);
	list_for_each_entry(me_cl, &bus->me_clients, list)
942
		mei_cl_bus_dev_init(bus, me_cl);
943
	up_read(&bus->me_clients_rwsem);
944

945
	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
946

947 948 949 950
		if (!mei_me_cl_is_active(cldev->me_cl)) {
			mei_cl_bus_remove_device(cldev);
			continue;
		}
951

952 953 954
		if (cldev->is_added)
			continue;

955
		if (mei_cl_bus_dev_setup(bus, cldev))
956 957 958 959 960 961 962 963 964
			mei_cl_bus_dev_add(cldev);
		else {
			list_del_init(&cldev->bus_list);
			put_device(&cldev->dev);
		}
	}
	mutex_unlock(&bus->cl_bus_lock);

	dev_dbg(bus->dev, "rescan end");
965
}
966

967 968 969 970
void mei_cl_bus_rescan_work(struct work_struct *work)
{
	struct mei_device *bus =
		container_of(work, struct mei_device, bus_rescan_work);
971 972 973 974 975 976 977 978
	struct mei_me_client *me_cl;

	mutex_lock(&bus->device_lock);
	me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
	if (me_cl)
		mei_amthif_host_init(bus, me_cl);
	mei_me_cl_put(me_cl);
	mutex_unlock(&bus->device_lock);
979 980 981 982

	mei_cl_bus_rescan(bus);
}

983 984
int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
				struct module *owner)
985 986
{
	int err;
987

988 989 990
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
991

992 993 994
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
995

996
	pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
997

998
	return 0;
999
}
1000
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1001

1002
void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1003
{
1004
	driver_unregister(&cldrv->driver);
1005

1006
	pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1007
}
1008
EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1009

1010

1011 1012 1013 1014 1015 1016 1017 1018 1019
int __init mei_cl_bus_init(void)
{
	return bus_register(&mei_cl_bus_type);
}

void __exit mei_cl_bus_exit(void)
{
	bus_unregister(&mei_cl_bus_type);
}