bus.c 22.8 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
	u8 version = mei_me_cl_ver(cldev->me_cl);
767

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

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

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

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

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

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

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

	return 0;
}
811

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

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

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

	if (!cldev)
		return;

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

B
Bhumika Goyal 已提交
848
static const struct device_type mei_cl_device_type = {
849
	.release	= mei_cl_bus_dev_release,
850 851
};

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

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

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

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

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

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

	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;

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

	return ret;
}

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

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

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 998 999
	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;

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


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

1021 1022
	WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));

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

	if (me_cl->bus_added)
		return;
1027

1028
	cldev = mei_cl_bus_dev_alloc(bus, me_cl);
1029
	if (!cldev)
1030
		return;
1031

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

1035
}
1036

1037 1038 1039 1040 1041 1042
/**
 * mei_cl_bus_rescan - scan me clients list and add create
 *    devices for eligible clients
 *
 * @bus: mei device
 */
1043
static void mei_cl_bus_rescan(struct mei_device *bus)
1044 1045 1046
{
	struct mei_cl_device *cldev, *n;
	struct mei_me_client *me_cl;
1047

1048 1049
	mutex_lock(&bus->cl_bus_lock);

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

1055
	list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
1056

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

1062 1063 1064
		if (cldev->is_added)
			continue;

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

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

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

1090 1091 1092
	cldrv->driver.name = cldrv->name;
	cldrv->driver.owner = owner;
	cldrv->driver.bus = &mei_cl_bus_type;
1093

1094 1095 1096
	err = driver_register(&cldrv->driver);
	if (err)
		return err;
1097

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

1100
	return 0;
1101
}
1102
EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1103

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

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

1112

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