linux/drivers/misc/mei/bus.c
<<
>>
Prefs
   1/*
   2 * Intel Management Engine Interface (Intel MEI) Linux driver
   3 * Copyright (c) 2012-2013, Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/device.h>
  18#include <linux/kernel.h>
  19#include <linux/sched.h>
  20#include <linux/init.h>
  21#include <linux/errno.h>
  22#include <linux/slab.h>
  23#include <linux/mutex.h>
  24#include <linux/interrupt.h>
  25#include <linux/mei_cl_bus.h>
  26
  27#include "mei_dev.h"
  28#include "client.h"
  29
  30#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
  31#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
  32
  33/**
  34 * __mei_cl_send - internal client send (write)
  35 *
  36 * @cl: host client
  37 * @buf: buffer to send
  38 * @length: buffer length
  39 * @blocking: wait for write completion
  40 *
  41 * Return: written size bytes or < 0 on error
  42 */
  43ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
  44                        bool blocking)
  45{
  46        struct mei_device *bus;
  47        struct mei_cl_cb *cb;
  48        ssize_t rets;
  49
  50        if (WARN_ON(!cl || !cl->dev))
  51                return -ENODEV;
  52
  53        bus = cl->dev;
  54
  55        mutex_lock(&bus->device_lock);
  56        if (bus->dev_state != MEI_DEV_ENABLED) {
  57                rets = -ENODEV;
  58                goto out;
  59        }
  60
  61        if (!mei_cl_is_connected(cl)) {
  62                rets = -ENODEV;
  63                goto out;
  64        }
  65
  66        /* Check if we have an ME client device */
  67        if (!mei_me_cl_is_active(cl->me_cl)) {
  68                rets = -ENOTTY;
  69                goto out;
  70        }
  71
  72        if (length > mei_cl_mtu(cl)) {
  73                rets = -EFBIG;
  74                goto out;
  75        }
  76
  77        cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
  78        if (!cb) {
  79                rets = -ENOMEM;
  80                goto out;
  81        }
  82
  83        memcpy(cb->buf.data, buf, length);
  84
  85        rets = mei_cl_write(cl, cb, blocking);
  86
  87out:
  88        mutex_unlock(&bus->device_lock);
  89
  90        return rets;
  91}
  92
  93/**
  94 * __mei_cl_recv - internal client receive (read)
  95 *
  96 * @cl: host client
  97 * @buf: buffer to receive
  98 * @length: buffer length
  99 *
 100 * Return: read size in bytes of < 0 on error
 101 */
 102ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
 103{
 104        struct mei_device *bus;
 105        struct mei_cl_cb *cb;
 106        size_t r_length;
 107        ssize_t rets;
 108
 109        if (WARN_ON(!cl || !cl->dev))
 110                return -ENODEV;
 111
 112        bus = cl->dev;
 113
 114        mutex_lock(&bus->device_lock);
 115        if (bus->dev_state != MEI_DEV_ENABLED) {
 116                rets = -ENODEV;
 117                goto out;
 118        }
 119
 120        cb = mei_cl_read_cb(cl, NULL);
 121        if (cb)
 122                goto copy;
 123
 124        rets = mei_cl_read_start(cl, length, NULL);
 125        if (rets && rets != -EBUSY)
 126                goto out;
 127
 128        /* wait on event only if there is no other waiter */
 129        /* synchronized under device mutex */
 130        if (!waitqueue_active(&cl->rx_wait)) {
 131
 132                mutex_unlock(&bus->device_lock);
 133
 134                if (wait_event_interruptible(cl->rx_wait,
 135                                (!list_empty(&cl->rd_completed)) ||
 136                                (!mei_cl_is_connected(cl)))) {
 137
 138                        if (signal_pending(current))
 139                                return -EINTR;
 140                        return -ERESTARTSYS;
 141                }
 142
 143                mutex_lock(&bus->device_lock);
 144
 145                if (!mei_cl_is_connected(cl)) {
 146                        rets = -ENODEV;
 147                        goto out;
 148                }
 149        }
 150
 151        cb = mei_cl_read_cb(cl, NULL);
 152        if (!cb) {
 153                rets = 0;
 154                goto out;
 155        }
 156
 157copy:
 158        if (cb->status) {
 159                rets = cb->status;
 160                goto free;
 161        }
 162
 163        r_length = min_t(size_t, length, cb->buf_idx);
 164        memcpy(buf, cb->buf.data, r_length);
 165        rets = r_length;
 166
 167free:
 168        mei_io_cb_free(cb);
 169out:
 170        mutex_unlock(&bus->device_lock);
 171
 172        return rets;
 173}
 174
 175/**
 176 * mei_cldev_send - me device send  (write)
 177 *
 178 * @cldev: me client device
 179 * @buf: buffer to send
 180 * @length: buffer length
 181 *
 182 * Return: written size in bytes or < 0 on error
 183 */
 184ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 185{
 186        struct mei_cl *cl = cldev->cl;
 187
 188        if (cl == NULL)
 189                return -ENODEV;
 190
 191        return __mei_cl_send(cl, buf, length, 1);
 192}
 193EXPORT_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 * @length: buffer length
 201 *
 202 * Return: read size in bytes of < 0 on error
 203 */
 204ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
 205{
 206        struct mei_cl *cl = cldev->cl;
 207
 208        if (cl == NULL)
 209                return -ENODEV;
 210
 211        return __mei_cl_recv(cl, buf, length);
 212}
 213EXPORT_SYMBOL_GPL(mei_cldev_recv);
 214
 215/**
 216 * mei_cl_bus_event_work  - dispatch rx event for a bus device
 217 *    and schedule new work
 218 *
 219 * @work: work
 220 */
 221static 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        bus = cldev->bus;
 229
 230        if (cldev->event_cb)
 231                cldev->event_cb(cldev, cldev->events, cldev->event_context);
 232
 233        cldev->events = 0;
 234
 235        /* Prepare for the next read */
 236        if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
 237                mutex_lock(&bus->device_lock);
 238                mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
 239                mutex_unlock(&bus->device_lock);
 240        }
 241}
 242
 243/**
 244 * mei_cl_bus_notify_event - schedule notify cb on bus client
 245 *
 246 * @cl: host client
 247 *
 248 * Return: true if event was scheduled
 249 *         false if the client is not waiting for event
 250 */
 251bool mei_cl_bus_notify_event(struct mei_cl *cl)
 252{
 253        struct mei_cl_device *cldev = cl->cldev;
 254
 255        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        set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);
 265
 266        schedule_work(&cldev->event_work);
 267
 268        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 * Return: true if event was scheduled
 279 *         false if the client is not waiting for event
 280 */
 281bool 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 * @cldev: me client devices
 302 * @event_cb: callback function
 303 * @events_mask: requested events bitmask
 304 * @context: driver context data
 305 *
 306 * Return: 0 on success
 307 *         -EALREADY if an callback is already registered
 308 *         <0 on other errors
 309 */
 310int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
 311                                unsigned long events_mask,
 312                                mei_cldev_event_cb_t event_cb, void *context)
 313{
 314        struct mei_device *bus = cldev->bus;
 315        int ret;
 316
 317        if (cldev->event_cb)
 318                return -EALREADY;
 319
 320        cldev->events = 0;
 321        cldev->events_mask = events_mask;
 322        cldev->event_cb = event_cb;
 323        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, mei_cl_mtu(cldev->cl), NULL);
 329                mutex_unlock(&bus->device_lock);
 330                if (ret && ret != -EBUSY)
 331                        return ret;
 332        }
 333
 334        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                if (ret)
 339                        return ret;
 340        }
 341
 342        return 0;
 343}
 344EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
 345
 346/**
 347 * mei_cldev_get_drvdata - driver data getter
 348 *
 349 * @cldev: mei client device
 350 *
 351 * Return: driver private data
 352 */
 353void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
 354{
 355        return dev_get_drvdata(&cldev->dev);
 356}
 357EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
 358
 359/**
 360 * mei_cldev_set_drvdata - driver data setter
 361 *
 362 * @cldev: mei client device
 363 * @data: data to store
 364 */
 365void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
 366{
 367        dev_set_drvdata(&cldev->dev, data);
 368}
 369EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
 370
 371/**
 372 * mei_cldev_uuid - return uuid of the underlying me client
 373 *
 374 * @cldev: mei client device
 375 *
 376 * Return: me client uuid
 377 */
 378const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
 379{
 380        return mei_me_cl_uuid(cldev->me_cl);
 381}
 382EXPORT_SYMBOL_GPL(mei_cldev_uuid);
 383
 384/**
 385 * mei_cldev_ver - return protocol version of the underlying me client
 386 *
 387 * @cldev: mei client device
 388 *
 389 * Return: me client protocol version
 390 */
 391u8 mei_cldev_ver(const struct mei_cl_device *cldev)
 392{
 393        return mei_me_cl_ver(cldev->me_cl);
 394}
 395EXPORT_SYMBOL_GPL(mei_cldev_ver);
 396
 397/**
 398 * mei_cldev_enabled - check whether the device is enabled
 399 *
 400 * @cldev: mei client device
 401 *
 402 * Return: true if me client is initialized and connected
 403 */
 404bool mei_cldev_enabled(struct mei_cl_device *cldev)
 405{
 406        return cldev->cl && mei_cl_is_connected(cldev->cl);
 407}
 408EXPORT_SYMBOL_GPL(mei_cldev_enabled);
 409
 410/**
 411 * mei_cldev_enable_device - enable me client device
 412 *     create connection with me client
 413 *
 414 * @cldev: me client device
 415 *
 416 * Return: 0 on success and < 0 on error
 417 */
 418int mei_cldev_enable(struct mei_cl_device *cldev)
 419{
 420        struct mei_device *bus = cldev->bus;
 421        struct mei_cl *cl;
 422        int ret;
 423
 424        cl = cldev->cl;
 425
 426        if (!cl) {
 427                mutex_lock(&bus->device_lock);
 428                cl = mei_cl_alloc_linked(bus);
 429                mutex_unlock(&bus->device_lock);
 430                if (IS_ERR(cl))
 431                        return PTR_ERR(cl);
 432                /* update pointers */
 433                cldev->cl = cl;
 434                cl->cldev = cldev;
 435        }
 436
 437        mutex_lock(&bus->device_lock);
 438        if (mei_cl_is_connected(cl)) {
 439                ret = 0;
 440                goto out;
 441        }
 442
 443        if (!mei_me_cl_is_active(cldev->me_cl)) {
 444                dev_err(&cldev->dev, "me client is not active\n");
 445                ret = -ENOTTY;
 446                goto out;
 447        }
 448
 449        ret = mei_cl_connect(cl, cldev->me_cl, NULL);
 450        if (ret < 0)
 451                dev_err(&cldev->dev, "cannot connect\n");
 452
 453out:
 454        mutex_unlock(&bus->device_lock);
 455
 456        return ret;
 457}
 458EXPORT_SYMBOL_GPL(mei_cldev_enable);
 459
 460/**
 461 * mei_cldev_disable - disable me client device
 462 *     disconnect form the me client
 463 *
 464 * @cldev: me client device
 465 *
 466 * Return: 0 on success and < 0 on error
 467 */
 468int mei_cldev_disable(struct mei_cl_device *cldev)
 469{
 470        struct mei_device *bus;
 471        struct mei_cl *cl;
 472        int err;
 473
 474        if (!cldev || !cldev->cl)
 475                return -ENODEV;
 476
 477        cl = cldev->cl;
 478
 479        bus = cldev->bus;
 480
 481        cldev->event_cb = NULL;
 482
 483        mutex_lock(&bus->device_lock);
 484
 485        if (!mei_cl_is_connected(cl)) {
 486                dev_err(bus->dev, "Already disconnected");
 487                err = 0;
 488                goto out;
 489        }
 490
 491        err = mei_cl_disconnect(cl);
 492        if (err < 0)
 493                dev_err(bus->dev, "Could not disconnect from the ME client");
 494
 495out:
 496        /* Flush queues and remove any pending read */
 497        mei_cl_flush_queues(cl, NULL);
 498        mei_cl_unlink(cl);
 499
 500        kfree(cl);
 501        cldev->cl = NULL;
 502
 503        mutex_unlock(&bus->device_lock);
 504        return err;
 505}
 506EXPORT_SYMBOL_GPL(mei_cldev_disable);
 507
 508/**
 509 * mei_cl_device_find - find matching entry in the driver id table
 510 *
 511 * @cldev: me client device
 512 * @cldrv: me client driver
 513 *
 514 * Return: id on success; NULL if no id is matching
 515 */
 516static const
 517struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
 518                                            struct mei_cl_driver *cldrv)
 519{
 520        const struct mei_cl_device_id *id;
 521        const uuid_le *uuid;
 522        u8 version;
 523        bool match;
 524
 525        uuid = mei_me_cl_uuid(cldev->me_cl);
 526        version = mei_me_cl_ver(cldev->me_cl);
 527
 528        id = cldrv->id_table;
 529        while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
 530                if (!uuid_le_cmp(*uuid, id->uuid)) {
 531                        match = true;
 532
 533                        if (cldev->name[0])
 534                                if (strncmp(cldev->name, id->name,
 535                                            sizeof(id->name)))
 536                                        match = false;
 537
 538                        if (id->version != MEI_CL_VERSION_ANY)
 539                                if (id->version != version)
 540                                        match = false;
 541                        if (match)
 542                                return id;
 543                }
 544
 545                id++;
 546        }
 547
 548        return NULL;
 549}
 550
 551/**
 552 * mei_cl_device_match  - device match function
 553 *
 554 * @dev: device
 555 * @drv: driver
 556 *
 557 * Return:  1 if matching device was found 0 otherwise
 558 */
 559static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
 560{
 561        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 562        struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
 563        const struct mei_cl_device_id *found_id;
 564
 565        if (!cldev)
 566                return 0;
 567
 568        if (!cldev->do_match)
 569                return 0;
 570
 571        if (!cldrv || !cldrv->id_table)
 572                return 0;
 573
 574        found_id = mei_cl_device_find(cldev, cldrv);
 575        if (found_id)
 576                return 1;
 577
 578        return 0;
 579}
 580
 581/**
 582 * mei_cl_device_probe - bus probe function
 583 *
 584 * @dev: device
 585 *
 586 * Return:  0 on success; < 0 otherwise
 587 */
 588static int mei_cl_device_probe(struct device *dev)
 589{
 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        cldev = to_mei_cl_device(dev);
 596        cldrv = to_mei_cl_driver(dev->driver);
 597
 598        if (!cldev)
 599                return 0;
 600
 601        if (!cldrv || !cldrv->probe)
 602                return -ENODEV;
 603
 604        id = mei_cl_device_find(cldev, cldrv);
 605        if (!id)
 606                return -ENODEV;
 607
 608        ret = cldrv->probe(cldev, id);
 609        if (ret)
 610                return ret;
 611
 612        __module_get(THIS_MODULE);
 613        return 0;
 614}
 615
 616/**
 617 * mei_cl_device_remove - remove device from the bus
 618 *
 619 * @dev: device
 620 *
 621 * Return:  0 on success; < 0 otherwise
 622 */
 623static int mei_cl_device_remove(struct device *dev)
 624{
 625        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 626        struct mei_cl_driver *cldrv;
 627        int ret = 0;
 628
 629        if (!cldev || !dev->driver)
 630                return 0;
 631
 632        if (cldev->event_cb) {
 633                cldev->event_cb = NULL;
 634                cancel_work_sync(&cldev->event_work);
 635        }
 636
 637        cldrv = to_mei_cl_driver(dev->driver);
 638        if (cldrv->remove)
 639                ret = cldrv->remove(cldev);
 640
 641        module_put(THIS_MODULE);
 642        dev->driver = NULL;
 643        return ret;
 644
 645}
 646
 647static ssize_t name_show(struct device *dev, struct device_attribute *a,
 648                             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}
 654static DEVICE_ATTR_RO(name);
 655
 656static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
 657                             char *buf)
 658{
 659        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 660        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 661
 662        return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
 663}
 664static DEVICE_ATTR_RO(uuid);
 665
 666static ssize_t version_show(struct device *dev, struct device_attribute *a,
 667                             char *buf)
 668{
 669        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 670        u8 version = mei_me_cl_ver(cldev->me_cl);
 671
 672        return scnprintf(buf, PAGE_SIZE, "%02X", version);
 673}
 674static DEVICE_ATTR_RO(version);
 675
 676static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 677                             char *buf)
 678{
 679        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 680        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}
 684static DEVICE_ATTR_RO(modalias);
 685
 686static struct attribute *mei_cldev_attrs[] = {
 687        &dev_attr_name.attr,
 688        &dev_attr_uuid.attr,
 689        &dev_attr_version.attr,
 690        &dev_attr_modalias.attr,
 691        NULL,
 692};
 693ATTRIBUTE_GROUPS(mei_cldev);
 694
 695/**
 696 * mei_cl_device_uevent - me client bus uevent handler
 697 *
 698 * @dev: device
 699 * @env: uevent kobject
 700 *
 701 * Return: 0 on success -ENOMEM on when add_uevent_var fails
 702 */
 703static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 704{
 705        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 706        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 707        u8 version = mei_me_cl_ver(cldev->me_cl);
 708
 709        if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
 710                return -ENOMEM;
 711
 712        if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
 713                return -ENOMEM;
 714
 715        if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
 716                return -ENOMEM;
 717
 718        if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
 719                           cldev->name, uuid, version))
 720                return -ENOMEM;
 721
 722        return 0;
 723}
 724
 725static struct bus_type mei_cl_bus_type = {
 726        .name           = "mei",
 727        .dev_groups     = mei_cldev_groups,
 728        .match          = mei_cl_device_match,
 729        .probe          = mei_cl_device_probe,
 730        .remove         = mei_cl_device_remove,
 731        .uevent         = mei_cl_device_uevent,
 732};
 733
 734static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
 735{
 736        if (bus)
 737                get_device(bus->dev);
 738
 739        return bus;
 740}
 741
 742static void mei_dev_bus_put(struct mei_device *bus)
 743{
 744        if (bus)
 745                put_device(bus->dev);
 746}
 747
 748static void mei_cl_bus_dev_release(struct device *dev)
 749{
 750        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 751
 752        if (!cldev)
 753                return;
 754
 755        mei_me_cl_put(cldev->me_cl);
 756        mei_dev_bus_put(cldev->bus);
 757        kfree(cldev);
 758}
 759
 760static struct device_type mei_cl_device_type = {
 761        .release        = mei_cl_bus_dev_release,
 762};
 763
 764/**
 765 * mei_cl_bus_set_name - set device name for me client device
 766 *
 767 * @cldev: me client device
 768 */
 769static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
 770{
 771        dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X",
 772                     cldev->name,
 773                     mei_me_cl_uuid(cldev->me_cl),
 774                     mei_me_cl_ver(cldev->me_cl));
 775}
 776
 777/**
 778 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
 779 *
 780 * @bus: mei device
 781 * @me_cl: me client
 782 *
 783 * Return: allocated device structur or NULL on allocation failure
 784 */
 785static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
 786                                                  struct mei_me_client *me_cl)
 787{
 788        struct mei_cl_device *cldev;
 789
 790        cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
 791        if (!cldev)
 792                return NULL;
 793
 794        device_initialize(&cldev->dev);
 795        cldev->dev.parent = bus->dev;
 796        cldev->dev.bus    = &mei_cl_bus_type;
 797        cldev->dev.type   = &mei_cl_device_type;
 798        cldev->bus        = mei_dev_bus_get(bus);
 799        cldev->me_cl      = mei_me_cl_get(me_cl);
 800        mei_cl_bus_set_name(cldev);
 801        cldev->is_added   = 0;
 802        INIT_LIST_HEAD(&cldev->bus_list);
 803
 804        return cldev;
 805}
 806
 807/**
 808 * mei_cl_dev_setup - setup me client device
 809 *    run fix up routines and set the device name
 810 *
 811 * @bus: mei device
 812 * @cldev: me client device
 813 *
 814 * Return: true if the device is eligible for enumeration
 815 */
 816static bool mei_cl_bus_dev_setup(struct mei_device *bus,
 817                                 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        return cldev->do_match == 1;
 827}
 828
 829/**
 830 * mei_cl_bus_dev_add - add me client devices
 831 *
 832 * @cldev: me client device
 833 *
 834 * Return: 0 on success; < 0 on failre
 835 */
 836static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
 837{
 838        int ret;
 839
 840        dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
 841                mei_me_cl_uuid(cldev->me_cl),
 842                mei_me_cl_ver(cldev->me_cl));
 843        ret = device_add(&cldev->dev);
 844        if (!ret)
 845                cldev->is_added = 1;
 846
 847        return ret;
 848}
 849
 850/**
 851 * mei_cl_bus_dev_stop - stop the driver
 852 *
 853 * @cldev: me client device
 854 */
 855static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
 856{
 857        if (cldev->is_added)
 858                device_release_driver(&cldev->dev);
 859}
 860
 861/**
 862 * mei_cl_bus_dev_destroy - destroy me client devices object
 863 *
 864 * @cldev: me client device
 865 *
 866 * Locking: called under "dev->cl_bus_lock" lock
 867 */
 868static 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        if (!cldev->is_added)
 874                return;
 875
 876        device_del(&cldev->dev);
 877
 878        list_del_init(&cldev->bus_list);
 879
 880        cldev->is_added = 0;
 881        put_device(&cldev->dev);
 882}
 883
 884/**
 885 * mei_cl_bus_remove_device - remove a devices form the bus
 886 *
 887 * @cldev: me client device
 888 */
 889static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
 890{
 891        mei_cl_bus_dev_stop(cldev);
 892        mei_cl_bus_dev_destroy(cldev);
 893}
 894
 895/**
 896 * mei_cl_bus_remove_devices - remove all devices form the bus
 897 *
 898 * @bus: mei device
 899 */
 900void mei_cl_bus_remove_devices(struct mei_device *bus)
 901{
 902        struct mei_cl_device *cldev, *next;
 903
 904        mutex_lock(&bus->cl_bus_lock);
 905        list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
 906                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 *     based on me client
 914 *
 915 * @bus: mei device
 916 * @me_cl: me client
 917 *
 918 * Locking: called under "dev->cl_bus_lock" lock
 919 */
 920static void mei_cl_bus_dev_init(struct mei_device *bus,
 921                                struct mei_me_client *me_cl)
 922{
 923        struct mei_cl_device *cldev;
 924
 925        WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));
 926
 927        dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
 928
 929        if (me_cl->bus_added)
 930                return;
 931
 932        cldev = mei_cl_bus_dev_alloc(bus, me_cl);
 933        if (!cldev)
 934                return;
 935
 936        me_cl->bus_added = true;
 937        list_add_tail(&cldev->bus_list, &bus->device_list);
 938
 939}
 940
 941/**
 942 * mei_cl_bus_rescan - scan me clients list and add create
 943 *    devices for eligible clients
 944 *
 945 * @bus: mei device
 946 */
 947void mei_cl_bus_rescan(struct mei_device *bus)
 948{
 949        struct mei_cl_device *cldev, *n;
 950        struct mei_me_client *me_cl;
 951
 952        mutex_lock(&bus->cl_bus_lock);
 953
 954        down_read(&bus->me_clients_rwsem);
 955        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                if (!mei_me_cl_is_active(cldev->me_cl)) {
 962                        mei_cl_bus_remove_device(cldev);
 963                        continue;
 964                }
 965
 966                if (cldev->is_added)
 967                        continue;
 968
 969                if (mei_cl_bus_dev_setup(bus, cldev))
 970                        mei_cl_bus_dev_add(cldev);
 971                else {
 972                        list_del_init(&cldev->bus_list);
 973                        put_device(&cldev->dev);
 974                }
 975        }
 976        mutex_unlock(&bus->cl_bus_lock);
 977
 978        dev_dbg(bus->dev, "rescan end");
 979}
 980
 981void mei_cl_bus_rescan_work(struct work_struct *work)
 982{
 983        struct mei_device *bus =
 984                container_of(work, struct mei_device, bus_rescan_work);
 985        struct mei_me_client *me_cl;
 986
 987        me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
 988        if (me_cl)
 989                mei_amthif_host_init(bus, me_cl);
 990        mei_me_cl_put(me_cl);
 991
 992        mei_cl_bus_rescan(bus);
 993}
 994
 995int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
 996                                struct module *owner)
 997{
 998        int err;
 999
1000        cldrv->driver.name = cldrv->name;
1001        cldrv->driver.owner = owner;
1002        cldrv->driver.bus = &mei_cl_bus_type;
1003
1004        err = driver_register(&cldrv->driver);
1005        if (err)
1006                return err;
1007
1008        pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
1009
1010        return 0;
1011}
1012EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1013
1014void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1015{
1016        driver_unregister(&cldrv->driver);
1017
1018        pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1019}
1020EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1021
1022
1023int __init mei_cl_bus_init(void)
1024{
1025        return bus_register(&mei_cl_bus_type);
1026}
1027
1028void __exit mei_cl_bus_exit(void)
1029{
1030        bus_unregister(&mei_cl_bus_type);
1031}
1032