bus.c 22.7 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/signal.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
 * @length: buffer length
101
 * @mode: io mode
102 103 104
 *
 * Return: read size in bytes of < 0 on error
 */
105 106
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
		      unsigned int mode)
107
{
108 109 110 111
	struct mei_device *bus;
	struct mei_cl_cb *cb;
	size_t r_length;
	ssize_t rets;
112
	bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK);
113

114
	if (WARN_ON(!cl || !cl->dev))
115 116
		return -ENODEV;

117
	bus = cl->dev;
118

119
	mutex_lock(&bus->device_lock);
120 121 122 123
	if (bus->dev_state != MEI_DEV_ENABLED) {
		rets = -ENODEV;
		goto out;
	}
124

125 126 127
	cb = mei_cl_read_cb(cl, NULL);
	if (cb)
		goto copy;
128

129 130 131
	rets = mei_cl_read_start(cl, length, NULL);
	if (rets && rets != -EBUSY)
		goto out;
132

133 134 135 136 137
	if (nonblock) {
		rets = -EAGAIN;
		goto out;
	}

138
	/* wait on event only if there is no other waiter */
139 140
	/* synchronized under device mutex */
	if (!waitqueue_active(&cl->rx_wait)) {
141

142
		mutex_unlock(&bus->device_lock);
143

144 145 146
		if (wait_event_interruptible(cl->rx_wait,
				(!list_empty(&cl->rd_completed)) ||
				(!mei_cl_is_connected(cl)))) {
147

148 149 150 151 152 153 154 155
			if (signal_pending(current))
				return -EINTR;
			return -ERESTARTSYS;
		}

		mutex_lock(&bus->device_lock);

		if (!mei_cl_is_connected(cl)) {
156
			rets = -ENODEV;
157 158
			goto out;
		}
159 160
	}

161 162 163 164 165
	cb = mei_cl_read_cb(cl, NULL);
	if (!cb) {
		rets = 0;
		goto out;
	}
166

167 168 169 170 171
copy:
	if (cb->status) {
		rets = cb->status;
		goto free;
	}
172

173 174 175
	r_length = min_t(size_t, length, cb->buf_idx);
	memcpy(buf, cb->buf.data, r_length);
	rets = r_length;
176

177 178 179 180 181 182
free:
	mei_io_cb_free(cb);
out:
	mutex_unlock(&bus->device_lock);

	return rets;
183 184
}

185
/**
186
 * mei_cldev_send - me device send  (write)
187 188 189 190 191 192 193
 *
 * @cldev: me client device
 * @buf: buffer to send
 * @length: buffer length
 *
 * Return: written size in bytes or < 0 on error
 */
194
ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
195
{
196
	struct mei_cl *cl = cldev->cl;
197

198
	return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
199
}
200
EXPORT_SYMBOL_GPL(mei_cldev_send);
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
/**
 * mei_cldev_recv_nonblock - non block client receive (read)
 *
 * @cldev: me client device
 * @buf: buffer to receive
 * @length: buffer length
 *
 * Return: read size in bytes of < 0 on error
 *         -EAGAIN if function will block.
 */
ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
				size_t length)
{
	struct mei_cl *cl = cldev->cl;

	return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK);
}
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);

221
/**
222
 * mei_cldev_recv - client receive (read)
223 224
 *
 * @cldev: me client device
225
 * @buf: buffer to receive
226 227 228 229
 * @length: buffer length
 *
 * Return: read size in bytes of < 0 on error
 */
230
ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
231
{
232
	struct mei_cl *cl = cldev->cl;
233

234
	return __mei_cl_recv(cl, buf, length, 0);
235
}
236
EXPORT_SYMBOL_GPL(mei_cldev_recv);
237

238
/**
239
 * mei_cl_bus_rx_work - dispatch rx event for a bus device
240 241 242
 *
 * @work: work
 */
243
static void mei_cl_bus_rx_work(struct work_struct *work)
244
{
245
	struct mei_cl_device *cldev;
246
	struct mei_device *bus;
247

248
	cldev = container_of(work, struct mei_cl_device, rx_work);
249

250 251
	bus = cldev->bus;

252 253
	if (cldev->rx_cb)
		cldev->rx_cb(cldev);
254

255 256 257 258
	mutex_lock(&bus->device_lock);
	mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
	mutex_unlock(&bus->device_lock);
}
259

260 261 262 263 264 265 266 267 268 269 270 271 272
/**
 * mei_cl_bus_notif_work - dispatch FW notif event for a bus device
 *
 * @work: work
 */
static void mei_cl_bus_notif_work(struct work_struct *work)
{
	struct mei_cl_device *cldev;

	cldev = container_of(work, struct mei_cl_device, notif_work);

	if (cldev->notif_cb)
		cldev->notif_cb(cldev);
273 274 275 276 277 278
}

/**
 * mei_cl_bus_notify_event - schedule notify cb on bus client
 *
 * @cl: host client
279 280 281
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
282
 */
283
bool mei_cl_bus_notify_event(struct mei_cl *cl)
284 285 286
{
	struct mei_cl_device *cldev = cl->cldev;

287
	if (!cldev || !cldev->notif_cb)
288
		return false;
289 290

	if (!cl->notify_ev)
291
		return false;
292

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

	cl->notify_ev = false;
296 297

	return true;
298 299
}

300
/**
301
 * mei_cl_bus_rx_event - schedule rx event
302 303
 *
 * @cl: host client
304 305 306
 *
 * Return: true if event was scheduled
 *         false if the client is not waiting for event
307
 */
308
bool mei_cl_bus_rx_event(struct mei_cl *cl)
309
{
310
	struct mei_cl_device *cldev = cl->cldev;
311

312
	if (!cldev || !cldev->rx_cb)
313
		return false;
314

315
	schedule_work(&cldev->rx_work);
316 317

	return true;
318
}
319

320
/**
321
 * mei_cldev_register_rx_cb - register Rx event callback
322 323
 *
 * @cldev: me client devices
324
 * @rx_cb: callback function
325 326 327 328 329
 *
 * Return: 0 on success
 *         -EALREADY if an callback is already registered
 *         <0 on other errors
 */
330
int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb)
331
{
332
	struct mei_device *bus = cldev->bus;
333 334
	int ret;

335 336 337
	if (!rx_cb)
		return -EINVAL;
	if (cldev->rx_cb)
338
		return -EALREADY;
339

340 341
	cldev->rx_cb = rx_cb;
	INIT_WORK(&cldev->rx_work, mei_cl_bus_rx_work);
342

343 344 345 346 347
	mutex_lock(&bus->device_lock);
	ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
	mutex_unlock(&bus->device_lock);
	if (ret && ret != -EBUSY)
		return ret;
348

349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
	return 0;
}
EXPORT_SYMBOL_GPL(mei_cldev_register_rx_cb);

/**
 * mei_cldev_register_notif_cb - register FW notification event callback
 *
 * @cldev: me client devices
 * @notif_cb: callback function
 *
 * Return: 0 on success
 *         -EALREADY if an callback is already registered
 *         <0 on other errors
 */
int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,
				mei_cldev_cb_t notif_cb)
{
	struct mei_device *bus = cldev->bus;
	int ret;

	if (!notif_cb)
		return -EINVAL;

	if (cldev->notif_cb)
		return -EALREADY;

	cldev->notif_cb = notif_cb;
	INIT_WORK(&cldev->notif_work, mei_cl_bus_notif_work);

	mutex_lock(&bus->device_lock);
	ret = mei_cl_notify_request(cldev->cl, NULL, 1);
	mutex_unlock(&bus->device_lock);
	if (ret)
		return ret;
383

384 385
	return 0;
}
386
EXPORT_SYMBOL_GPL(mei_cldev_register_notif_cb);
387

388
/**
389
 * mei_cldev_get_drvdata - driver data getter
390 391 392 393 394
 *
 * @cldev: mei client device
 *
 * Return: driver private data
 */
395
void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
396 397
{
	return dev_get_drvdata(&cldev->dev);
398
}
399
EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
400

401
/**
402
 * mei_cldev_set_drvdata - driver data setter
403 404 405 406
 *
 * @cldev: mei client device
 * @data: data to store
 */
407
void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
408
{
409
	dev_set_drvdata(&cldev->dev, data);
410
}
411
EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
412

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
/**
 * 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);

439 440 441 442 443 444 445 446 447
/**
 * 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)
{
448
	return mei_cl_is_connected(cldev->cl);
449 450 451
}
EXPORT_SYMBOL_GPL(mei_cldev_enabled);

452
/**
453
 * mei_cldev_enable - enable me client device
454 455 456 457 458 459
 *     create connection with me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
460
int mei_cldev_enable(struct mei_cl_device *cldev)
461
{
462 463 464
	struct mei_device *bus = cldev->bus;
	struct mei_cl *cl;
	int ret;
465

466
	cl = cldev->cl;
467

468
	if (cl->state == MEI_FILE_UNINITIALIZED) {
469
		mutex_lock(&bus->device_lock);
470
		ret = mei_cl_link(cl);
471
		mutex_unlock(&bus->device_lock);
472 473
		if (ret)
			return ret;
474 475 476
		/* update pointers */
		cl->cldev = cldev;
	}
477

478 479
	mutex_lock(&bus->device_lock);
	if (mei_cl_is_connected(cl)) {
480 481
		ret = 0;
		goto out;
482
	}
483

484 485 486 487
	if (!mei_me_cl_is_active(cldev->me_cl)) {
		dev_err(&cldev->dev, "me client is not active\n");
		ret = -ENOTTY;
		goto out;
488 489
	}

490 491 492 493 494
	ret = mei_cl_connect(cl, cldev->me_cl, NULL);
	if (ret < 0)
		dev_err(&cldev->dev, "cannot connect\n");

out:
495 496
	mutex_unlock(&bus->device_lock);

497
	return ret;
498
}
499
EXPORT_SYMBOL_GPL(mei_cldev_enable);
500

501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
/**
 * mei_cldev_unregister_callbacks - internal wrapper for unregistering
 *  callbacks.
 *
 * @cldev: client device
 */
static void mei_cldev_unregister_callbacks(struct mei_cl_device *cldev)
{
	if (cldev->rx_cb) {
		cancel_work_sync(&cldev->rx_work);
		cldev->rx_cb = NULL;
	}

	if (cldev->notif_cb) {
		cancel_work_sync(&cldev->notif_work);
		cldev->notif_cb = NULL;
	}
}

520
/**
521
 * mei_cldev_disable - disable me client device
522 523 524 525 526 527
 *     disconnect form the me client
 *
 * @cldev: me client device
 *
 * Return: 0 on success and < 0 on error
 */
528
int mei_cldev_disable(struct mei_cl_device *cldev)
529
{
530
	struct mei_device *bus;
531 532
	struct mei_cl *cl;
	int err;
533

534
	if (!cldev)
535 536
		return -ENODEV;

537 538 539
	cl = cldev->cl;

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

541 542
	mei_cldev_unregister_callbacks(cldev);

543
	mutex_lock(&bus->device_lock);
T
Tomas Winkler 已提交
544

545
	if (!mei_cl_is_connected(cl)) {
546
		dev_dbg(bus->dev, "Already disconnected");
547
		err = 0;
548 549
		goto out;
	}
T
Tomas Winkler 已提交
550

551
	err = mei_cl_disconnect(cl);
552
	if (err < 0)
553
		dev_err(bus->dev, "Could not disconnect from the ME client");
554

555
out:
556 557
	/* Flush queues and remove any pending read */
	mei_cl_flush_queues(cl, NULL);
558 559
	mei_cl_unlink(cl);

560
	mutex_unlock(&bus->device_lock);
561
	return err;
562
}
563
EXPORT_SYMBOL_GPL(mei_cldev_disable);
564

565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
/**
 * mei_cl_bus_module_get - acquire module of the underlying
 *    hw module.
 *
 * @cl: host client
 *
 * Return: true on success; false if the module was removed.
 */
bool mei_cl_bus_module_get(struct mei_cl *cl)
{
	struct mei_cl_device *cldev = cl->cldev;

	if (!cldev)
		return true;

	return try_module_get(cldev->bus->dev->driver->owner);
}

/**
 * mei_cl_bus_module_put -  release the underlying hw module.
 *
 * @cl: host client
 */
void mei_cl_bus_module_put(struct mei_cl *cl)
{
	struct mei_cl_device *cldev = cl->cldev;

	if (cldev)
		module_put(cldev->bus->dev->driver->owner);
}

T
Tomas Winkler 已提交
596 597 598 599 600 601 602 603 604 605 606
/**
 * 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)
607
{
608 609
	const struct mei_cl_device_id *id;
	const uuid_le *uuid;
610 611
	u8 version;
	bool match;
612

613
	uuid = mei_me_cl_uuid(cldev->me_cl);
614
	version = mei_me_cl_ver(cldev->me_cl);
615

616 617 618
	id = cldrv->id_table;
	while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
		if (!uuid_le_cmp(*uuid, id->uuid)) {
619
			match = true;
T
Tomas Winkler 已提交
620

621 622 623 624
			if (cldev->name[0])
				if (strncmp(cldev->name, id->name,
					    sizeof(id->name)))
					match = false;
T
Tomas Winkler 已提交
625

626 627 628 629
			if (id->version != MEI_CL_VERSION_ANY)
				if (id->version != version)
					match = false;
			if (match)
T
Tomas Winkler 已提交
630
				return id;
631
		}
632

633 634
		id++;
	}
635

T
Tomas Winkler 已提交
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
	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;

656 657 658
	if (!cldev->do_match)
		return 0;

T
Tomas Winkler 已提交
659 660 661 662 663 664 665
	if (!cldrv || !cldrv->id_table)
		return 0;

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

666 667
	return 0;
}
668

669 670 671 672 673 674 675
/**
 * mei_cl_device_probe - bus probe function
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
676 677
static int mei_cl_device_probe(struct device *dev)
{
678
	struct mei_cl_device *cldev;
679
	struct mei_cl_driver *cldrv;
680
	const struct mei_cl_device_id *id;
681
	int ret;
682 683 684

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

686 687
	if (!cldev)
		return 0;
688

689 690 691
	if (!cldrv || !cldrv->probe)
		return -ENODEV;

692 693 694
	id = mei_cl_device_find(cldev, cldrv);
	if (!id)
		return -ENODEV;
695

696 697 698
	ret = cldrv->probe(cldev, id);
	if (ret)
		return ret;
699

700 701
	__module_get(THIS_MODULE);
	return 0;
702
}
703

704 705 706 707 708 709 710
/**
 * mei_cl_device_remove - remove device from the bus
 *
 * @dev: device
 *
 * Return:  0 on success; < 0 otherwise
 */
711 712 713 714
static int mei_cl_device_remove(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct mei_cl_driver *cldrv;
715
	int ret = 0;
716

717 718 719
	if (!cldev || !dev->driver)
		return 0;

720 721 722 723
	cldrv = to_mei_cl_driver(dev->driver);
	if (cldrv->remove)
		ret = cldrv->remove(cldev);

724
	mei_cldev_unregister_callbacks(cldev);
725

726 727 728
	module_put(THIS_MODULE);
	dev->driver = NULL;
	return ret;
729 730 731

}

732 733
static ssize_t name_show(struct device *dev, struct device_attribute *a,
			     char *buf)
734
{
735
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
736

737
	return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
738
}
739
static DEVICE_ATTR_RO(name);
740

741 742
static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
			     char *buf)
743
{
744 745
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
746

747
	return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
748
}
749
static DEVICE_ATTR_RO(uuid);
750

751 752 753 754 755 756
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);

757
	return scnprintf(buf, PAGE_SIZE, "%02X", version);
758 759 760
}
static DEVICE_ATTR_RO(version);

761 762
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
763
{
764 765
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
766

767
	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
768
}
769
static DEVICE_ATTR_RO(modalias);
770

771
static struct attribute *mei_cldev_attrs[] = {
772 773
	&dev_attr_name.attr,
	&dev_attr_uuid.attr,
774
	&dev_attr_version.attr,
775 776 777
	&dev_attr_modalias.attr,
	NULL,
};
778
ATTRIBUTE_GROUPS(mei_cldev);
779

780 781 782 783 784 785 786 787 788
/**
 * 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)
789
{
790 791
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
792 793 794 795
	u8 version = mei_me_cl_ver(cldev->me_cl);

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

797 798
	if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
		return -ENOMEM;
799

800 801 802
	if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
		return -ENOMEM;

803 804
	if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
			   cldev->name, uuid, version))
805
		return -ENOMEM;
806 807 808

	return 0;
}
809

810 811
static struct bus_type mei_cl_bus_type = {
	.name		= "mei",
812
	.dev_groups	= mei_cldev_groups,
813 814 815
	.match		= mei_cl_device_match,
	.probe		= mei_cl_device_probe,
	.remove		= mei_cl_device_remove,
816
	.uevent		= mei_cl_device_uevent,
817 818
};

819 820 821 822 823 824 825 826 827 828 829 830 831 832
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);
}

833
static void mei_cl_bus_dev_release(struct device *dev)
834
{
835 836 837 838 839 840
	struct mei_cl_device *cldev = to_mei_cl_device(dev);

	if (!cldev)
		return;

	mei_me_cl_put(cldev->me_cl);
841
	mei_dev_bus_put(cldev->bus);
842
	kfree(cldev->cl);
843
	kfree(cldev);
844 845
}

846
static struct device_type mei_cl_device_type = {
847
	.release	= mei_cl_bus_dev_release,
848 849
};

850 851 852 853 854 855 856 857 858 859 860 861 862
/**
 * 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));
}

863
/**
864
 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
865 866 867 868 869 870
 *
 * @bus: mei device
 * @me_cl: me client
 *
 * Return: allocated device structur or NULL on allocation failure
 */
871 872
static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
						  struct mei_me_client *me_cl)
873 874
{
	struct mei_cl_device *cldev;
875
	struct mei_cl *cl;
876 877 878 879 880

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

881 882 883 884 885 886
	cl = mei_cl_allocate(bus);
	if (!cl) {
		kfree(cldev);
		return NULL;
	}

887 888 889 890 891 892
	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);
893
	cldev->cl         = cl;
894
	mei_cl_bus_set_name(cldev);
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
	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
 */
910 911
static bool mei_cl_bus_dev_setup(struct mei_device *bus,
				 struct mei_cl_device *cldev)
912 913
{
	cldev->do_match = 1;
914
	mei_cl_bus_dev_fixup(cldev);
915

916
	/* the device name can change during fix up */
917
	if (cldev->do_match)
918
		mei_cl_bus_set_name(cldev);
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933

	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;

934 935 936
	dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
		mei_me_cl_uuid(cldev->me_cl),
		mei_me_cl_ver(cldev->me_cl));
937 938 939 940 941 942 943
	ret = device_add(&cldev->dev);
	if (!ret)
		cldev->is_added = 1;

	return ret;
}

944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
/**
 * 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
959 960
 *
 * Locking: called under "dev->cl_bus_lock" lock
961 962 963
 */
static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
{
964 965 966

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

967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
	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;

998
	mutex_lock(&bus->cl_bus_lock);
999 1000
	list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
		mei_cl_bus_remove_device(cldev);
1001
	mutex_unlock(&bus->cl_bus_lock);
1002 1003 1004 1005
}


/**
1006
 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
1007 1008 1009 1010
 *     based on me client
 *
 * @bus: mei device
 * @me_cl: me client
1011 1012
 *
 * Locking: called under "dev->cl_bus_lock" lock
1013
 */
1014 1015
static void mei_cl_bus_dev_init(struct mei_device *bus,
				struct mei_me_client *me_cl)
1016
{
1017
	struct mei_cl_device *cldev;
1018

1019 1020
	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));

1021 1022 1023 1024
	dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));

	if (me_cl->bus_added)
		return;
1025

1026
	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
1027
	if (!cldev)
1028
		return;
1029

1030 1031
	me_cl->bus_added = true;
	list_add_tail(&cldev->bus_list, &bus->device_list);
T
Tomas Winkler 已提交
1032

1033
}
1034

1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
/**
 * 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;
1045

1046 1047
	mutex_lock(&bus->cl_bus_lock);

1048 1049
	down_read(&bus->me_clients_rwsem);
	list_for_each_entry(me_cl, &bus->me_clients, list)
1050
		mei_cl_bus_dev_init(bus, me_cl);
1051
	up_read(&bus->me_clients_rwsem);
1052

1053
	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
1054

1055 1056 1057 1058
		if (!mei_me_cl_is_active(cldev->me_cl)) {
			mei_cl_bus_remove_device(cldev);
			continue;
		}
1059

1060 1061 1062
		if (cldev->is_added)
			continue;

1063
		if (mei_cl_bus_dev_setup(bus, cldev))
1064 1065 1066 1067 1068 1069 1070 1071 1072
			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");
1073
}
1074

1075 1076 1077 1078 1079 1080 1081 1082
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);
}

1083 1084
int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
				struct module *owner)
1085 1086
{
	int err;
1087

1088 1089 1090
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
1091

1092 1093 1094
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
1095

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

1098
	return 0;
1099
}
1100
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1101

1102
void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1103
{
1104
	driver_unregister(&cldrv->driver);
1105

1106
	pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1107
}
1108
EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1109

1110

1111 1112 1113 1114 1115 1116 1117 1118 1119
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);
}