bus.c 21.1 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
	/* wait on event only if there is no other waiter */
129 130
	/* synchronized under device mutex */
	if (!waitqueue_active(&cl->rx_wait)) {
131

132
		mutex_unlock(&bus->device_lock);
133

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

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

		mutex_lock(&bus->device_lock);

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

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

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

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

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

	return rets;
173 174
}

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

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

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

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

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

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

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

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

228 229
	bus = cldev->bus;

230 231
	if (cldev->event_cb)
		cldev->event_cb(cldev, cldev->events, cldev->event_context);
232

233
	cldev->events = 0;
234

235
	/* Prepare for the next read */
236 237
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
		mutex_lock(&bus->device_lock);
238
		mei_cl_read_start(cldev->cl, 0, NULL);
239 240
		mutex_unlock(&bus->device_lock);
	}
241 242 243 244 245 246
}

/**
 * mei_cl_bus_notify_event - schedule notify cb on bus client
 *
 * @cl: host client
247 248 249
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
250
 */
251
bool mei_cl_bus_notify_event(struct mei_cl *cl)
252 253 254 255
{
	struct mei_cl_device *cldev = cl->cldev;

	if (!cldev || !cldev->event_cb)
256
		return false;
257 258

	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
259
		return false;
260 261

	if (!cl->notify_ev)
262
		return false;
263 264 265 266 267 268

	set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);

	schedule_work(&cldev->event_work);

	cl->notify_ev = false;
269 270

	return true;
271 272
}

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

285
	if (!cldev || !cldev->event_cb)
286
		return false;
287

288
	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX)))
289
		return false;
290

291
	set_bit(MEI_CL_EVENT_RX, &cldev->events);
292

293
	schedule_work(&cldev->event_work);
294 295

	return true;
296
}
297

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

317 318
	if (cldev->event_cb)
		return -EALREADY;
319

320
	cldev->events = 0;
321
	cldev->events_mask = events_mask;
322 323
	cldev->event_cb = event_cb;
	cldev->event_context = context;
324
	INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
325

326
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
327
		mutex_lock(&bus->device_lock);
328
		ret = mei_cl_read_start(cldev->cl, 0, NULL);
329
		mutex_unlock(&bus->device_lock);
330 331 332 333 334
		if (ret && ret != -EBUSY)
			return ret;
	}

	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
335
		mutex_lock(&bus->device_lock);
336
		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
337
		mutex_unlock(&bus->device_lock);
338 339 340
		if (ret)
			return ret;
	}
341

342 343
	return 0;
}
344
EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
345

346
/**
347
 * mei_cldev_get_drvdata - driver data getter
348 349 350 351 352
 *
 * @cldev: mei client device
 *
 * Return: driver private data
 */
353
void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
354 355
{
	return dev_get_drvdata(&cldev->dev);
356
}
357
EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
358

359
/**
360
 * mei_cldev_set_drvdata - driver data setter
361 362 363 364
 *
 * @cldev: mei client device
 * @data: data to store
 */
365
void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
366
{
367
	dev_set_drvdata(&cldev->dev, data);
368
}
369
EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
370

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
/**
 * 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);

397 398 399 400 401 402 403 404 405 406 407 408 409
/**
 * 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);

410
/**
411
 * mei_cldev_enable_device - enable me client device
412 413 414 415 416 417
 *     create connection with me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
418
int mei_cldev_enable(struct mei_cl_device *cldev)
419
{
420 421 422
	struct mei_device *bus = cldev->bus;
	struct mei_cl *cl;
	int ret;
423

424
	cl = cldev->cl;
425

426 427
	if (!cl) {
		mutex_lock(&bus->device_lock);
428
		cl = mei_cl_alloc_linked(bus);
429 430 431 432 433 434 435
		mutex_unlock(&bus->device_lock);
		if (IS_ERR(cl))
			return PTR_ERR(cl);
		/* update pointers */
		cldev->cl = cl;
		cl->cldev = cldev;
	}
436

437 438
	mutex_lock(&bus->device_lock);
	if (mei_cl_is_connected(cl)) {
439 440
		ret = 0;
		goto out;
441
	}
442

443 444 445 446
	if (!mei_me_cl_is_active(cldev->me_cl)) {
		dev_err(&cldev->dev, "me client is not active\n");
		ret = -ENOTTY;
		goto out;
447 448
	}

449 450 451 452 453
	ret = mei_cl_connect(cl, cldev->me_cl, NULL);
	if (ret < 0)
		dev_err(&cldev->dev, "cannot connect\n");

out:
454 455
	mutex_unlock(&bus->device_lock);

456
	return ret;
457
}
458
EXPORT_SYMBOL_GPL(mei_cldev_enable);
459

460
/**
461
 * mei_cldev_disable - disable me client device
462 463 464 465 466 467
 *     disconnect form the me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
468
int mei_cldev_disable(struct mei_cl_device *cldev)
469
{
470
	struct mei_device *bus;
471 472
	struct mei_cl *cl;
	int err;
473

474
	if (!cldev || !cldev->cl)
475 476
		return -ENODEV;

477 478 479
	cl = cldev->cl;

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

481
	cldev->event_cb = NULL;
482

483
	mutex_lock(&bus->device_lock);
T
Tomas Winkler 已提交
484

485 486 487
	if (!mei_cl_is_connected(cl)) {
		dev_err(bus->dev, "Already disconnected");
		err = 0;
488 489
		goto out;
	}
T
Tomas Winkler 已提交
490

491
	err = mei_cl_disconnect(cl);
492
	if (err < 0)
493
		dev_err(bus->dev, "Could not disconnect from the ME client");
494

495
out:
496 497
	/* Flush queues and remove any pending read */
	mei_cl_flush_queues(cl, NULL);
498 499 500 501
	mei_cl_unlink(cl);

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

503
	mutex_unlock(&bus->device_lock);
504
	return err;
505
}
506
EXPORT_SYMBOL_GPL(mei_cldev_disable);
507

T
Tomas Winkler 已提交
508 509 510 511 512 513 514 515 516 517 518
/**
 * 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)
519
{
520 521
	const struct mei_cl_device_id *id;
	const uuid_le *uuid;
522 523
	u8 version;
	bool match;
524

525
	uuid = mei_me_cl_uuid(cldev->me_cl);
526
	version = mei_me_cl_ver(cldev->me_cl);
527

528 529 530
	id = cldrv->id_table;
	while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
		if (!uuid_le_cmp(*uuid, id->uuid)) {
531
			match = true;
T
Tomas Winkler 已提交
532

533 534 535 536
			if (cldev->name[0])
				if (strncmp(cldev->name, id->name,
					    sizeof(id->name)))
					match = false;
T
Tomas Winkler 已提交
537

538 539 540 541
			if (id->version != MEI_CL_VERSION_ANY)
				if (id->version != version)
					match = false;
			if (match)
T
Tomas Winkler 已提交
542
				return id;
543
		}
544

545 546
		id++;
	}
547

T
Tomas Winkler 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
	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;

568 569 570
	if (!cldev->do_match)
		return 0;

T
Tomas Winkler 已提交
571 572 573 574 575 576 577
	if (!cldrv || !cldrv->id_table)
		return 0;

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

578 579
	return 0;
}
580

581 582 583 584 585 586 587
/**
 * mei_cl_device_probe - bus probe function
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
588 589
static int mei_cl_device_probe(struct device *dev)
{
590
	struct mei_cl_device *cldev;
591
	struct mei_cl_driver *cldrv;
592
	const struct mei_cl_device_id *id;
593
	int ret;
594 595 596

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

598 599
	if (!cldev)
		return 0;
600

601 602 603
	if (!cldrv || !cldrv->probe)
		return -ENODEV;

604 605 606
	id = mei_cl_device_find(cldev, cldrv);
	if (!id)
		return -ENODEV;
607

608 609 610
	ret = cldrv->probe(cldev, id);
	if (ret)
		return ret;
611

612 613
	__module_get(THIS_MODULE);
	return 0;
614
}
615

616 617 618 619 620 621 622
/**
 * mei_cl_device_remove - remove device from the bus
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
623 624 625 626
static int mei_cl_device_remove(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct mei_cl_driver *cldrv;
627
	int ret = 0;
628

629 630 631 632 633 634
	if (!cldev || !dev->driver)
		return 0;

	if (cldev->event_cb) {
		cldev->event_cb = NULL;
		cancel_work_sync(&cldev->event_work);
635 636
	}

637
	cldrv = to_mei_cl_driver(dev->driver);
638 639
	if (cldrv->remove)
		ret = cldrv->remove(cldev);
640

641 642 643
	module_put(THIS_MODULE);
	dev->driver = NULL;
	return ret;
644 645 646

}

647 648
static ssize_t name_show(struct device *dev, struct device_attribute *a,
			     char *buf)
649
{
650
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
651

652
	return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
653
}
654
static DEVICE_ATTR_RO(name);
655

656 657
static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
			     char *buf)
658
{
659 660
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
661

662
	return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
663
}
664
static DEVICE_ATTR_RO(uuid);
665

666 667 668 669 670 671
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);

672
	return scnprintf(buf, PAGE_SIZE, "%02X", version);
673 674 675
}
static DEVICE_ATTR_RO(version);

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

682
	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
683
}
684
static DEVICE_ATTR_RO(modalias);
685

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

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

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

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

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

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

	return 0;
}
724

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

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

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

	if (!cldev)
		return;

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

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

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

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

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

	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;

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

	return ret;
}

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

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

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 903
	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;

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


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

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

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

	if (me_cl->bus_added)
		return;
931

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

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

939
}
940

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

952 953
	mutex_lock(&bus->cl_bus_lock);

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

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

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

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

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

981 982 983 984
void mei_cl_bus_rescan_work(struct work_struct *work)
{
	struct mei_device *bus =
		container_of(work, struct mei_device, bus_rescan_work);
985 986 987 988 989 990 991 992
	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);
993 994 995 996

	mei_cl_bus_rescan(bus);
}

997 998
int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
				struct module *owner)
999 1000
{
	int err;
1001

1002 1003 1004
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
1005

1006 1007 1008
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
1009

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

1012
	return 0;
1013
}
1014
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1015

1016
void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1017
{
1018
	driver_unregister(&cldrv->driver);
1019

1020
	pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1021
}
1022
EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1023

1024

1025 1026 1027 1028 1029 1030 1031 1032 1033
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);
}