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
	const struct mei_cl_device_id *id;
583
	int ret;
584 585 586

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

588 589
	if (!cldev)
		return 0;
590

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

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

598 599 600
	ret = cldrv->probe(cldev, id);
	if (ret)
		return ret;
601

602 603
	__module_get(THIS_MODULE);
	return 0;
604
}
605

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

619 620 621 622 623 624
	if (!cldev || !dev->driver)
		return 0;

	if (cldev->event_cb) {
		cldev->event_cb = NULL;
		cancel_work_sync(&cldev->event_work);
625 626
	}

627
	cldrv = to_mei_cl_driver(dev->driver);
628 629
	if (cldrv->remove)
		ret = cldrv->remove(cldev);
630

631 632 633
	module_put(THIS_MODULE);
	dev->driver = NULL;
	return ret;
634 635 636

}

637 638
static ssize_t name_show(struct device *dev, struct device_attribute *a,
			     char *buf)
639
{
640
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
641

642
	return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
643
}
644
static DEVICE_ATTR_RO(name);
645

646 647
static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
			     char *buf)
648
{
649 650
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
651

652
	return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
653
}
654
static DEVICE_ATTR_RO(uuid);
655

656 657 658 659 660 661
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);

662
	return scnprintf(buf, PAGE_SIZE, "%02X", version);
663 664 665
}
static DEVICE_ATTR_RO(version);

666 667
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
668
{
669 670
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
671

672
	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
673
}
674
static DEVICE_ATTR_RO(modalias);
675

676
static struct attribute *mei_cldev_attrs[] = {
677 678
	&dev_attr_name.attr,
	&dev_attr_uuid.attr,
679
	&dev_attr_version.attr,
680 681 682
	&dev_attr_modalias.attr,
	NULL,
};
683
ATTRIBUTE_GROUPS(mei_cldev);
684

685 686 687 688 689 690 691 692 693
/**
 * 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)
694
{
695 696
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
697 698 699 700
	u8 version = mei_me_cl_ver(cldev->me_cl);

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

702 703
	if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
		return -ENOMEM;
704

705 706 707
	if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
		return -ENOMEM;

708 709
	if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
			   cldev->name, uuid, version))
710
		return -ENOMEM;
711 712 713

	return 0;
}
714

715 716
static struct bus_type mei_cl_bus_type = {
	.name		= "mei",
717
	.dev_groups	= mei_cldev_groups,
718 719 720
	.match		= mei_cl_device_match,
	.probe		= mei_cl_device_probe,
	.remove		= mei_cl_device_remove,
721
	.uevent		= mei_cl_device_uevent,
722 723
};

724 725 726 727 728 729 730 731 732 733 734 735 736 737
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);
}

738
static void mei_cl_bus_dev_release(struct device *dev)
739
{
740 741 742 743 744 745
	struct mei_cl_device *cldev = to_mei_cl_device(dev);

	if (!cldev)
		return;

	mei_me_cl_put(cldev->me_cl);
746
	mei_dev_bus_put(cldev->bus);
747
	kfree(cldev);
748 749
}

750
static struct device_type mei_cl_device_type = {
751
	.release	= mei_cl_bus_dev_release,
752 753
};

754 755 756 757 758 759 760 761 762 763 764 765 766
/**
 * 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));
}

767
/**
768
 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
769 770 771 772 773 774
 *
 * @bus: mei device
 * @me_cl: me client
 *
 * Return: allocated device structur or NULL on allocation failure
 */
775 776
static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
						  struct mei_me_client *me_cl)
777 778 779 780 781 782 783 784 785 786 787 788 789
{
	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);
790
	mei_cl_bus_set_name(cldev);
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
	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
 */
806 807
static bool mei_cl_bus_dev_setup(struct mei_device *bus,
				 struct mei_cl_device *cldev)
808 809
{
	cldev->do_match = 1;
810
	mei_cl_bus_dev_fixup(cldev);
811

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

	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;

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

	return ret;
}

840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
/**
 * 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
855 856
 *
 * Locking: called under "dev->cl_bus_lock" lock
857 858 859
 */
static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
{
860 861 862

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

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 890 891 892 893
	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;

894
	mutex_lock(&bus->cl_bus_lock);
895 896
	list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
		mei_cl_bus_remove_device(cldev);
897
	mutex_unlock(&bus->cl_bus_lock);
898 899 900 901
}


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

915 916
	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));

917 918 919 920
	dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));

	if (me_cl->bus_added)
		return;
921

922
	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
923
	if (!cldev)
924
		return;
925

926 927
	me_cl->bus_added = true;
	list_add_tail(&cldev->bus_list, &bus->device_list);
T
Tomas Winkler 已提交
928

929
}
930

931 932 933 934 935 936 937 938 939 940
/**
 * 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;
941

942 943
	mutex_lock(&bus->cl_bus_lock);

944 945
	down_read(&bus->me_clients_rwsem);
	list_for_each_entry(me_cl, &bus->me_clients, list)
946
		mei_cl_bus_dev_init(bus, me_cl);
947
	up_read(&bus->me_clients_rwsem);
948

949
	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
950

951 952 953 954
		if (!mei_me_cl_is_active(cldev->me_cl)) {
			mei_cl_bus_remove_device(cldev);
			continue;
		}
955

956 957 958
		if (cldev->is_added)
			continue;

959
		if (mei_cl_bus_dev_setup(bus, cldev))
960 961 962 963 964 965 966 967 968
			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");
969
}
970

971 972 973 974
void mei_cl_bus_rescan_work(struct work_struct *work)
{
	struct mei_device *bus =
		container_of(work, struct mei_device, bus_rescan_work);
975 976 977 978 979 980 981 982
	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);
983 984 985 986

	mei_cl_bus_rescan(bus);
}

987 988
int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
				struct module *owner)
989 990
{
	int err;
991

992 993 994
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
995

996 997 998
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
999

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

1002
	return 0;
1003
}
1004
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1005

1006
void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1007
{
1008
	driver_unregister(&cldrv->driver);
1009

1010
	pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1011
}
1012
EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1013

1014

1015 1016 1017 1018 1019 1020 1021 1022 1023
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);
}