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
/**
 * __mei_cl_send - internal client send (write)
 *
 * @cl: host client
 * @buf: buffer to send
 * @length: buffer length
39
 * @mode: sending mode
40 41 42 43
 *
 * Return: written size bytes or < 0 on error
 */
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
44
		      unsigned int mode)
45
{
46
	struct mei_device *bus;
47
	struct mei_cl_cb *cb;
48
	ssize_t rets;
49

50 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
	cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
	cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
85 86
	memcpy(cb->buf.data, buf, length);

87
	rets = mei_cl_write(cl, cb);
88 89 90 91 92

out:
	mutex_unlock(&bus->device_lock);

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

134
		mutex_unlock(&bus->device_lock);
135

136 137 138
		if (wait_event_interruptible(cl->rx_wait,
				(!list_empty(&cl->rd_completed)) ||
				(!mei_cl_is_connected(cl)))) {
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)) {
148
			rets = -ENODEV;
149 150
			goto out;
		}
151 152
	}

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

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

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

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

	return rets;
175 176
}

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

190
	return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
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
	return __mei_cl_recv(cl, buf, length);
208
}
209
EXPORT_SYMBOL_GPL(mei_cldev_recv);
210

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

222
	cldev = container_of(work, struct mei_cl_device, event_work);
223

224 225
	bus = cldev->bus;

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

229
	cldev->events = 0;
230

231
	/* Prepare for the next read */
232 233
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
		mutex_lock(&bus->device_lock);
234
		mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
235 236
		mutex_unlock(&bus->device_lock);
	}
237 238 239 240 241 242
}

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

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

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

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

	set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);

	schedule_work(&cldev->event_work);

	cl->notify_ev = false;
265 266

	return true;
267 268
}

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

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

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

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

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

	return true;
292
}
293

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

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

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

320
	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
321
		mutex_lock(&bus->device_lock);
322
		ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
323
		mutex_unlock(&bus->device_lock);
324 325 326 327 328
		if (ret && ret != -EBUSY)
			return ret;
	}

	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
329
		mutex_lock(&bus->device_lock);
330
		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
331
		mutex_unlock(&bus->device_lock);
332 333 334
		if (ret)
			return ret;
	}
335

336 337
	return 0;
}
338
EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
339

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

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

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)
{
400
	return mei_cl_is_connected(cldev->cl);
401 402 403
}
EXPORT_SYMBOL_GPL(mei_cldev_enabled);

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

418
	cl = cldev->cl;
419

420
	if (cl->state == MEI_FILE_UNINITIALIZED) {
421
		mutex_lock(&bus->device_lock);
422
		ret = mei_cl_link(cl);
423
		mutex_unlock(&bus->device_lock);
424 425
		if (ret)
			return ret;
426 427 428
		/* update pointers */
		cl->cldev = cldev;
	}
429

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

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

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

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

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

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

467
	if (!cldev)
468 469
		return -ENODEV;

470 471 472
	cl = cldev->cl;

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

474
	cldev->event_cb = NULL;
475

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

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

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

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

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->cl);
748
	kfree(cldev);
749 750
}

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

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

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

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

786 787 788 789 790 791
	cl = mei_cl_allocate(bus);
	if (!cl) {
		kfree(cldev);
		return NULL;
	}

792 793 794 795 796 797
	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);
798
	cldev->cl         = 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
void mei_cl_bus_rescan_work(struct work_struct *work)
{
	struct mei_device *bus =
		container_of(work, struct mei_device, bus_rescan_work);
984 985 986 987 988 989
	struct mei_me_client *me_cl;

	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);
990 991 992 993

	mei_cl_bus_rescan(bus);
}

994 995
int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
				struct module *owner)
996 997
{
	int err;
998

999 1000 1001
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
1002

1003 1004 1005
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
1006

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

1009
	return 0;
1010
}
1011
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1012

1013
void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1014
{
1015
	driver_unregister(&cldrv->driver);
1016

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

1021

1022 1023 1024 1025 1026 1027 1028 1029 1030
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);
}