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 47 48
	struct mei_device *bus;
	struct mei_cl_cb *cb = NULL;
	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 91 92
	memcpy(cb->buf.data, buf, length);

	rets = mei_cl_write(cl, cb, blocking);

out:
	mutex_unlock(&bus->device_lock);
	if (rets < 0)
		mei_io_cb_free(cb);

	return rets;
93 94
}

95 96 97 98
/**
 * __mei_cl_recv - internal client receive (read)
 *
 * @cl: host client
99
 * @buf: buffer to receive
100 101 102 103 104
 * @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)
105
{
106 107 108 109
	struct mei_device *bus;
	struct mei_cl_cb *cb;
	size_t r_length;
	ssize_t rets;
110

111
	if (WARN_ON(!cl || !cl->dev))
112 113
		return -ENODEV;

114
	bus = cl->dev;
115

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

122 123 124
	cb = mei_cl_read_cb(cl, NULL);
	if (cb)
		goto copy;
125

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

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

133
		mutex_unlock(&bus->device_lock);
134

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

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

		mutex_lock(&bus->device_lock);

		if (!mei_cl_is_connected(cl)) {
			rets = -EBUSY;
			goto out;
		}
150 151
	}

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

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

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

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

	return rets;
174 175
}

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

189 190
	if (cl == NULL)
		return -ENODEV;
191

192
	return __mei_cl_send(cl, buf, length, 1);
193
}
194
EXPORT_SYMBOL_GPL(mei_cldev_send);
195

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

209 210
	if (cl == NULL)
		return -ENODEV;
211

212
	return __mei_cl_recv(cl, buf, length);
213
}
214
EXPORT_SYMBOL_GPL(mei_cldev_recv);
215

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

226
	cldev = container_of(work, struct mei_cl_device, event_work);
227

228 229
	if (cldev->event_cb)
		cldev->event_cb(cldev, cldev->events, cldev->event_context);
230

231
	cldev->events = 0;
232

233
	/* Prepare for the next read */
234 235 236 237 238 239 240 241
	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
242 243 244
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
245
 */
246
bool mei_cl_bus_notify_event(struct mei_cl *cl)
247 248 249 250
{
	struct mei_cl_device *cldev = cl->cldev;

	if (!cldev || !cldev->event_cb)
251
		return false;
252 253

	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
254
		return false;
255 256

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

	set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);

	schedule_work(&cldev->event_work);

	cl->notify_ev = false;
264 265

	return true;
266 267
}

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

280
	if (!cldev || !cldev->event_cb)
281
		return false;
282

283
	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX)))
284
		return false;
285

286
	set_bit(MEI_CL_EVENT_RX, &cldev->events);
287

288
	schedule_work(&cldev->event_work);
289 290

	return true;
291
}
292

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

311 312
	if (cldev->event_cb)
		return -EALREADY;
313

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

320 321 322 323 324 325 326 327 328 329 330 331 332
	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;
	}
333

334 335
	return 0;
}
336
EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
337

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

351
/**
352
 * mei_cldev_set_drvdata - driver data setter
353 354 355 356
 *
 * @cldev: mei client device
 * @data: data to store
 */
357
void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
358
{
359
	dev_set_drvdata(&cldev->dev, data);
360
}
361
EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
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 387 388
/**
 * 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);

389 390 391 392 393 394 395 396 397 398 399 400 401
/**
 * 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);

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

416
	cl = cldev->cl;
417

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

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

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

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

out:
446 447
	mutex_unlock(&bus->device_lock);

448
	return ret;
449
}
450
EXPORT_SYMBOL_GPL(mei_cldev_enable);
451

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

466
	if (!cldev || !cldev->cl)
467 468
		return -ENODEV;

469 470 471
	cl = cldev->cl;

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

473
	cldev->event_cb = NULL;
474

475
	mutex_lock(&bus->device_lock);
T
Tomas Winkler 已提交
476

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

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

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

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

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

T
Tomas Winkler 已提交
500 501 502 503 504 505 506 507 508 509 510
/**
 * 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)
511
{
512 513
	const struct mei_cl_device_id *id;
	const uuid_le *uuid;
514 515
	u8 version;
	bool match;
516

517
	uuid = mei_me_cl_uuid(cldev->me_cl);
518
	version = mei_me_cl_ver(cldev->me_cl);
519

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

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

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

537 538
		id++;
	}
539

T
Tomas Winkler 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
	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;

560 561 562
	if (!cldev->do_match)
		return 0;

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

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

570 571
	return 0;
}
572

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

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

589 590
	if (!cldev)
		return 0;
591

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

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

599
	__module_get(THIS_MODULE);
600

601
	return cldrv->probe(cldev, id);
602
}
603

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

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

	if (cldev->event_cb) {
		cldev->event_cb = NULL;
		cancel_work_sync(&cldev->event_work);
623 624
	}

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

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

}

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

641
	len = snprintf(buf, PAGE_SIZE, "%s", cldev->name);
642

643
	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
644
}
645
static DEVICE_ATTR_RO(name);
646

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

654
	len = snprintf(buf, PAGE_SIZE, "%pUl", uuid);
655

656
	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
657
}
658
static DEVICE_ATTR_RO(uuid);
659

660 661 662 663 664 665 666 667 668 669 670 671 672
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);
	size_t len;

	len = snprintf(buf, PAGE_SIZE, "%02X", version);

	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
static DEVICE_ATTR_RO(version);

673 674
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
675
{
676 677 678
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
	size_t len;
679

680
	len = snprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
681
	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
682
}
683
static DEVICE_ATTR_RO(modalias);
684

685
static struct attribute *mei_cldev_attrs[] = {
686 687
	&dev_attr_name.attr,
	&dev_attr_uuid.attr,
688
	&dev_attr_version.attr,
689 690 691
	&dev_attr_modalias.attr,
	NULL,
};
692
ATTRIBUTE_GROUPS(mei_cldev);
693

694 695 696 697 698 699 700 701 702
/**
 * 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)
703
{
704 705
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
706 707 708 709
	u8 version = mei_me_cl_ver(cldev->me_cl);

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

711 712
	if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
		return -ENOMEM;
713

714 715 716
	if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
		return -ENOMEM;

717 718
	if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
			   cldev->name, uuid, version))
719
		return -ENOMEM;
720 721 722

	return 0;
}
723

724 725
static struct bus_type mei_cl_bus_type = {
	.name		= "mei",
726
	.dev_groups	= mei_cldev_groups,
727 728 729
	.match		= mei_cl_device_match,
	.probe		= mei_cl_device_probe,
	.remove		= mei_cl_device_remove,
730
	.uevent		= mei_cl_device_uevent,
731 732
};

733 734 735 736 737 738 739 740 741 742 743 744 745 746
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);
}

747
static void mei_cl_bus_dev_release(struct device *dev)
748
{
749 750 751 752 753 754
	struct mei_cl_device *cldev = to_mei_cl_device(dev);

	if (!cldev)
		return;

	mei_me_cl_put(cldev->me_cl);
755
	mei_dev_bus_put(cldev->bus);
756
	kfree(cldev);
757 758
}

759
static struct device_type mei_cl_device_type = {
760
	.release	= mei_cl_bus_dev_release,
761 762
};

763 764 765 766 767 768 769 770 771 772 773 774 775
/**
 * 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));
}

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

821
	/* the device name can change during fix up */
822
	if (cldev->do_match)
823
		mei_cl_bus_set_name(cldev);
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838

	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;

839 840 841
	dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
		mei_me_cl_uuid(cldev->me_cl),
		mei_me_cl_ver(cldev->me_cl));
842 843 844 845 846 847 848
	ret = device_add(&cldev->dev);
	if (!ret)
		cldev->is_added = 1;

	return ret;
}

849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
/**
 * 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
864 865
 *
 * Locking: called under "dev->cl_bus_lock" lock
866 867 868
 */
static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
{
869 870 871

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

872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
	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;

903
	mutex_lock(&bus->cl_bus_lock);
904 905
	list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
		mei_cl_bus_remove_device(cldev);
906
	mutex_unlock(&bus->cl_bus_lock);
907 908 909 910
}


/**
911
 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
912 913 914 915
 *     based on me client
 *
 * @bus: mei device
 * @me_cl: me client
916 917
 *
 * Locking: called under "dev->cl_bus_lock" lock
918
 */
919 920
static void mei_cl_bus_dev_init(struct mei_device *bus,
				struct mei_me_client *me_cl)
921
{
922
	struct mei_cl_device *cldev;
923

924 925
	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));

926 927 928 929
	dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));

	if (me_cl->bus_added)
		return;
930

931
	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
932
	if (!cldev)
933
		return;
934

935 936
	me_cl->bus_added = true;
	list_add_tail(&cldev->bus_list, &bus->device_list);
T
Tomas Winkler 已提交
937

938
}
939

940 941 942 943 944 945 946 947 948 949
/**
 * 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;
950

951 952
	mutex_lock(&bus->cl_bus_lock);

953 954
	down_read(&bus->me_clients_rwsem);
	list_for_each_entry(me_cl, &bus->me_clients, list)
955
		mei_cl_bus_dev_init(bus, me_cl);
956
	up_read(&bus->me_clients_rwsem);
957

958
	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
959

960 961 962 963
		if (!mei_me_cl_is_active(cldev->me_cl)) {
			mei_cl_bus_remove_device(cldev);
			continue;
		}
964

965 966 967
		if (cldev->is_added)
			continue;

968
		if (mei_cl_bus_dev_setup(bus, cldev))
969 970 971 972 973 974 975 976 977
			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");
978
}
979

980 981 982 983 984 985 986 987
void mei_cl_bus_rescan_work(struct work_struct *work)
{
	struct mei_device *bus =
		container_of(work, struct mei_device, bus_rescan_work);

	mei_cl_bus_rescan(bus);
}

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

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

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

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

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

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

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

1015

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