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        if (list_empty(&cl->rd_completed) && !waitqueue_active(&cl->rx_wait)) {
 130
 131                mutex_unlock(&bus->device_lock);
 132
 133                if (wait_event_interruptible(cl->rx_wait,
 134                                (!list_empty(&cl->rd_completed)) ||
 135                                (!mei_cl_is_connected(cl)))) {
 136
 137                        if (signal_pending(current))
 138                                return -EINTR;
 139                        return -ERESTARTSYS;
 140                }
 141
 142                mutex_lock(&bus->device_lock);
 143
 144                if (!mei_cl_is_connected(cl)) {
 145                        rets = -EBUSY;
 146                        goto out;
 147                }
 148        }
 149
 150        cb = mei_cl_read_cb(cl, NULL);
 151        if (!cb) {
 152                rets = 0;
 153                goto out;
 154        }
 155
 156copy:
 157        if (cb->status) {
 158                rets = cb->status;
 159                goto free;
 160        }
 161
 162        r_length = min_t(size_t, length, cb->buf_idx);
 163        memcpy(buf, cb->buf.data, r_length);
 164        rets = r_length;
 165
 166free:
 167        mei_io_cb_free(cb);
 168out:
 169        mutex_unlock(&bus->device_lock);
 170
 171        return rets;
 172}
 173
 174/**
 175 * mei_cldev_send - me device send  (write)
 176 *
 177 * @cldev: me client device
 178 * @buf: buffer to send
 179 * @length: buffer length
 180 *
 181 * Return: written size in bytes or < 0 on error
 182 */
 183ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 184{
 185        struct mei_cl *cl = cldev->cl;
 186
 187        if (cl == NULL)
 188                return -ENODEV;
 189
 190        return __mei_cl_send(cl, buf, length, 1);
 191}
 192EXPORT_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 * @length: buffer length
 200 *
 201 * Return: read size in bytes of < 0 on error
 202 */
 203ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
 204{
 205        struct mei_cl *cl = cldev->cl;
 206
 207        if (cl == NULL)
 208                return -ENODEV;
 209
 210        return __mei_cl_recv(cl, buf, length);
 211}
 212EXPORT_SYMBOL_GPL(mei_cldev_recv);
 213
 214/**
 215 * mei_cl_bus_event_work  - dispatch rx event for a bus device
 216 *    and schedule new work
 217 *
 218 * @work: work
 219 */
 220static void mei_cl_bus_event_work(struct work_struct *work)
 221{
 222        struct mei_cl_device *cldev;
 223
 224        cldev = container_of(work, struct mei_cl_device, event_work);
 225
 226        if (cldev->event_cb)
 227                cldev->event_cb(cldev, cldev->events, cldev->event_context);
 228
 229        cldev->events = 0;
 230
 231        /* Prepare for the next read */
 232        if (cldev->events_mask & BIT(MEI_CL_EVENT_RX))
 233                mei_cl_read_start(cldev->cl, 0, NULL);
 234}
 235
 236/**
 237 * mei_cl_bus_notify_event - schedule notify cb on bus client
 238 *
 239 * @cl: host client
 240 *
 241 * Return: true if event was scheduled
 242 *         false if the client is not waiting for event
 243 */
 244bool mei_cl_bus_notify_event(struct mei_cl *cl)
 245{
 246        struct mei_cl_device *cldev = cl->cldev;
 247
 248        if (!cldev || !cldev->event_cb)
 249                return false;
 250
 251        if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
 252                return false;
 253
 254        if (!cl->notify_ev)
 255                return false;
 256
 257        set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);
 258
 259        schedule_work(&cldev->event_work);
 260
 261        cl->notify_ev = false;
 262
 263        return true;
 264}
 265
 266/**
 267 * mei_cl_bus_rx_event  - schedule rx event
 268 *
 269 * @cl: host client
 270 *
 271 * Return: true if event was scheduled
 272 *         false if the client is not waiting for event
 273 */
 274bool mei_cl_bus_rx_event(struct mei_cl *cl)
 275{
 276        struct mei_cl_device *cldev = cl->cldev;
 277
 278        if (!cldev || !cldev->event_cb)
 279                return false;
 280
 281        if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX)))
 282                return false;
 283
 284        set_bit(MEI_CL_EVENT_RX, &cldev->events);
 285
 286        schedule_work(&cldev->event_work);
 287
 288        return true;
 289}
 290
 291/**
 292 * mei_cldev_register_event_cb - register event callback
 293 *
 294 * @cldev: me client devices
 295 * @event_cb: callback function
 296 * @events_mask: requested events bitmask
 297 * @context: driver context data
 298 *
 299 * Return: 0 on success
 300 *         -EALREADY if an callback is already registered
 301 *         <0 on other errors
 302 */
 303int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
 304                                unsigned long events_mask,
 305                                mei_cldev_event_cb_t event_cb, void *context)
 306{
 307        int ret;
 308
 309        if (cldev->event_cb)
 310                return -EALREADY;
 311
 312        cldev->events = 0;
 313        cldev->events_mask = events_mask;
 314        cldev->event_cb = event_cb;
 315        cldev->event_context = context;
 316        INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
 317
 318        if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
 319                ret = mei_cl_read_start(cldev->cl, 0, NULL);
 320                if (ret && ret != -EBUSY)
 321                        return ret;
 322        }
 323
 324        if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
 325                mutex_lock(&cldev->cl->dev->device_lock);
 326                ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
 327                mutex_unlock(&cldev->cl->dev->device_lock);
 328                if (ret)
 329                        return ret;
 330        }
 331
 332        return 0;
 333}
 334EXPORT_SYMBOL_GPL(mei_cldev_register_event_cb);
 335
 336/**
 337 * mei_cldev_get_drvdata - driver data getter
 338 *
 339 * @cldev: mei client device
 340 *
 341 * Return: driver private data
 342 */
 343void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
 344{
 345        return dev_get_drvdata(&cldev->dev);
 346}
 347EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
 348
 349/**
 350 * mei_cldev_set_drvdata - driver data setter
 351 *
 352 * @cldev: mei client device
 353 * @data: data to store
 354 */
 355void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
 356{
 357        dev_set_drvdata(&cldev->dev, data);
 358}
 359EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
 360
 361/**
 362 * mei_cldev_uuid - return uuid of the underlying me client
 363 *
 364 * @cldev: mei client device
 365 *
 366 * Return: me client uuid
 367 */
 368const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
 369{
 370        return mei_me_cl_uuid(cldev->me_cl);
 371}
 372EXPORT_SYMBOL_GPL(mei_cldev_uuid);
 373
 374/**
 375 * mei_cldev_ver - return protocol version of the underlying me client
 376 *
 377 * @cldev: mei client device
 378 *
 379 * Return: me client protocol version
 380 */
 381u8 mei_cldev_ver(const struct mei_cl_device *cldev)
 382{
 383        return mei_me_cl_ver(cldev->me_cl);
 384}
 385EXPORT_SYMBOL_GPL(mei_cldev_ver);
 386
 387/**
 388 * mei_cldev_enabled - check whether the device is enabled
 389 *
 390 * @cldev: mei client device
 391 *
 392 * Return: true if me client is initialized and connected
 393 */
 394bool mei_cldev_enabled(struct mei_cl_device *cldev)
 395{
 396        return cldev->cl && mei_cl_is_connected(cldev->cl);
 397}
 398EXPORT_SYMBOL_GPL(mei_cldev_enabled);
 399
 400/**
 401 * mei_cldev_enable_device - enable me client device
 402 *     create connection with me client
 403 *
 404 * @cldev: me client device
 405 *
 406 * Return: 0 on success and < 0 on error
 407 */
 408int mei_cldev_enable(struct mei_cl_device *cldev)
 409{
 410        struct mei_device *bus = cldev->bus;
 411        struct mei_cl *cl;
 412        int ret;
 413
 414        cl = cldev->cl;
 415
 416        if (!cl) {
 417                mutex_lock(&bus->device_lock);
 418                cl = mei_cl_alloc_linked(bus);
 419                mutex_unlock(&bus->device_lock);
 420                if (IS_ERR(cl))
 421                        return PTR_ERR(cl);
 422                /* update pointers */
 423                cldev->cl = cl;
 424                cl->cldev = cldev;
 425        }
 426
 427        mutex_lock(&bus->device_lock);
 428        if (mei_cl_is_connected(cl)) {
 429                ret = 0;
 430                goto out;
 431        }
 432
 433        if (!mei_me_cl_is_active(cldev->me_cl)) {
 434                dev_err(&cldev->dev, "me client is not active\n");
 435                ret = -ENOTTY;
 436                goto out;
 437        }
 438
 439        ret = mei_cl_connect(cl, cldev->me_cl, NULL);
 440        if (ret < 0)
 441                dev_err(&cldev->dev, "cannot connect\n");
 442
 443out:
 444        mutex_unlock(&bus->device_lock);
 445
 446        return ret;
 447}
 448EXPORT_SYMBOL_GPL(mei_cldev_enable);
 449
 450/**
 451 * mei_cldev_disable - disable me client device
 452 *     disconnect form the me client
 453 *
 454 * @cldev: me client device
 455 *
 456 * Return: 0 on success and < 0 on error
 457 */
 458int mei_cldev_disable(struct mei_cl_device *cldev)
 459{
 460        struct mei_device *bus;
 461        struct mei_cl *cl;
 462        int err;
 463
 464        if (!cldev || !cldev->cl)
 465                return -ENODEV;
 466
 467        cl = cldev->cl;
 468
 469        bus = cldev->bus;
 470
 471        cldev->event_cb = NULL;
 472
 473        mutex_lock(&bus->device_lock);
 474
 475        if (!mei_cl_is_connected(cl)) {
 476                dev_err(bus->dev, "Already disconnected");
 477                err = 0;
 478                goto out;
 479        }
 480
 481        err = mei_cl_disconnect(cl);
 482        if (err < 0)
 483                dev_err(bus->dev, "Could not disconnect from the ME client");
 484
 485out:
 486        /* Flush queues and remove any pending read */
 487        mei_cl_flush_queues(cl, NULL);
 488        mei_cl_unlink(cl);
 489
 490        kfree(cl);
 491        cldev->cl = NULL;
 492
 493        mutex_unlock(&bus->device_lock);
 494        return err;
 495}
 496EXPORT_SYMBOL_GPL(mei_cldev_disable);
 497
 498/**
 499 * mei_cl_device_find - find matching entry in the driver id table
 500 *
 501 * @cldev: me client device
 502 * @cldrv: me client driver
 503 *
 504 * Return: id on success; NULL if no id is matching
 505 */
 506static const
 507struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
 508                                            struct mei_cl_driver *cldrv)
 509{
 510        const struct mei_cl_device_id *id;
 511        const uuid_le *uuid;
 512        u8 version;
 513        bool match;
 514
 515        uuid = mei_me_cl_uuid(cldev->me_cl);
 516        version = mei_me_cl_ver(cldev->me_cl);
 517
 518        id = cldrv->id_table;
 519        while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
 520                if (!uuid_le_cmp(*uuid, id->uuid)) {
 521                        match = true;
 522
 523                        if (cldev->name[0])
 524                                if (strncmp(cldev->name, id->name,
 525                                            sizeof(id->name)))
 526                                        match = false;
 527
 528                        if (id->version != MEI_CL_VERSION_ANY)
 529                                if (id->version != version)
 530                                        match = false;
 531                        if (match)
 532                                return id;
 533                }
 534
 535                id++;
 536        }
 537
 538        return NULL;
 539}
 540
 541/**
 542 * mei_cl_device_match  - device match function
 543 *
 544 * @dev: device
 545 * @drv: driver
 546 *
 547 * Return:  1 if matching device was found 0 otherwise
 548 */
 549static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
 550{
 551        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 552        struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
 553        const struct mei_cl_device_id *found_id;
 554
 555        if (!cldev)
 556                return 0;
 557
 558        if (!cldev->do_match)
 559                return 0;
 560
 561        if (!cldrv || !cldrv->id_table)
 562                return 0;
 563
 564        found_id = mei_cl_device_find(cldev, cldrv);
 565        if (found_id)
 566                return 1;
 567
 568        return 0;
 569}
 570
 571/**
 572 * mei_cl_device_probe - bus probe function
 573 *
 574 * @dev: device
 575 *
 576 * Return:  0 on success; < 0 otherwise
 577 */
 578static int mei_cl_device_probe(struct device *dev)
 579{
 580        struct mei_cl_device *cldev;
 581        struct mei_cl_driver *cldrv;
 582        const struct mei_cl_device_id *id;
 583
 584        cldev = to_mei_cl_device(dev);
 585        cldrv = to_mei_cl_driver(dev->driver);
 586
 587        if (!cldev)
 588                return 0;
 589
 590        if (!cldrv || !cldrv->probe)
 591                return -ENODEV;
 592
 593        id = mei_cl_device_find(cldev, cldrv);
 594        if (!id)
 595                return -ENODEV;
 596
 597        __module_get(THIS_MODULE);
 598
 599        return cldrv->probe(cldev, id);
 600}
 601
 602/**
 603 * mei_cl_device_remove - remove device from the bus
 604 *
 605 * @dev: device
 606 *
 607 * Return:  0 on success; < 0 otherwise
 608 */
 609static int mei_cl_device_remove(struct device *dev)
 610{
 611        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 612        struct mei_cl_driver *cldrv;
 613        int ret = 0;
 614
 615        if (!cldev || !dev->driver)
 616                return 0;
 617
 618        if (cldev->event_cb) {
 619                cldev->event_cb = NULL;
 620                cancel_work_sync(&cldev->event_work);
 621        }
 622
 623        cldrv = to_mei_cl_driver(dev->driver);
 624        if (cldrv->remove)
 625                ret = cldrv->remove(cldev);
 626
 627        module_put(THIS_MODULE);
 628        dev->driver = NULL;
 629        return ret;
 630
 631}
 632
 633static ssize_t name_show(struct device *dev, struct device_attribute *a,
 634                             char *buf)
 635{
 636        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 637        size_t len;
 638
 639        len = snprintf(buf, PAGE_SIZE, "%s", cldev->name);
 640
 641        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 642}
 643static DEVICE_ATTR_RO(name);
 644
 645static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
 646                             char *buf)
 647{
 648        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 649        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 650        size_t len;
 651
 652        len = snprintf(buf, PAGE_SIZE, "%pUl", uuid);
 653
 654        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 655}
 656static DEVICE_ATTR_RO(uuid);
 657
 658static ssize_t version_show(struct device *dev, struct device_attribute *a,
 659                             char *buf)
 660{
 661        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 662        u8 version = mei_me_cl_ver(cldev->me_cl);
 663        size_t len;
 664
 665        len = snprintf(buf, PAGE_SIZE, "%02X", version);
 666
 667        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 668}
 669static DEVICE_ATTR_RO(version);
 670
 671static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 672                             char *buf)
 673{
 674        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 675        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 676        size_t len;
 677
 678        len = snprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
 679        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 680}
 681static DEVICE_ATTR_RO(modalias);
 682
 683static struct attribute *mei_cldev_attrs[] = {
 684        &dev_attr_name.attr,
 685        &dev_attr_uuid.attr,
 686        &dev_attr_version.attr,
 687        &dev_attr_modalias.attr,
 688        NULL,
 689};
 690ATTRIBUTE_GROUPS(mei_cldev);
 691
 692/**
 693 * mei_cl_device_uevent - me client bus uevent handler
 694 *
 695 * @dev: device
 696 * @env: uevent kobject
 697 *
 698 * Return: 0 on success -ENOMEM on when add_uevent_var fails
 699 */
 700static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 701{
 702        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 703        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 704        u8 version = mei_me_cl_ver(cldev->me_cl);
 705
 706        if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
 707                return -ENOMEM;
 708
 709        if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
 710                return -ENOMEM;
 711
 712        if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
 713                return -ENOMEM;
 714
 715        if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
 716                           cldev->name, uuid, version))
 717                return -ENOMEM;
 718
 719        return 0;
 720}
 721
 722static struct bus_type mei_cl_bus_type = {
 723        .name           = "mei",
 724        .dev_groups     = mei_cldev_groups,
 725        .match          = mei_cl_device_match,
 726        .probe          = mei_cl_device_probe,
 727        .remove         = mei_cl_device_remove,
 728        .uevent         = mei_cl_device_uevent,
 729};
 730
 731static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
 732{
 733        if (bus)
 734                get_device(bus->dev);
 735
 736        return bus;
 737}
 738
 739static void mei_dev_bus_put(struct mei_device *bus)
 740{
 741        if (bus)
 742                put_device(bus->dev);
 743}
 744
 745static void mei_cl_bus_dev_release(struct device *dev)
 746{
 747        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 748
 749        if (!cldev)
 750                return;
 751
 752        mei_me_cl_put(cldev->me_cl);
 753        mei_dev_bus_put(cldev->bus);
 754        kfree(cldev);
 755}
 756
 757static struct device_type mei_cl_device_type = {
 758        .release        = mei_cl_bus_dev_release,
 759};
 760
 761/**
 762 * mei_cl_bus_set_name - set device name for me client device
 763 *
 764 * @cldev: me client device
 765 */
 766static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
 767{
 768        dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X",
 769                     cldev->name,
 770                     mei_me_cl_uuid(cldev->me_cl),
 771                     mei_me_cl_ver(cldev->me_cl));
 772}
 773
 774/**
 775 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
 776 *
 777 * @bus: mei device
 778 * @me_cl: me client
 779 *
 780 * Return: allocated device structur or NULL on allocation failure
 781 */
 782static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
 783                                                  struct mei_me_client *me_cl)
 784{
 785        struct mei_cl_device *cldev;
 786
 787        cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
 788        if (!cldev)
 789                return NULL;
 790
 791        device_initialize(&cldev->dev);
 792        cldev->dev.parent = bus->dev;
 793        cldev->dev.bus    = &mei_cl_bus_type;
 794        cldev->dev.type   = &mei_cl_device_type;
 795        cldev->bus        = mei_dev_bus_get(bus);
 796        cldev->me_cl      = mei_me_cl_get(me_cl);
 797        mei_cl_bus_set_name(cldev);
 798        cldev->is_added   = 0;
 799        INIT_LIST_HEAD(&cldev->bus_list);
 800
 801        return cldev;
 802}
 803
 804/**
 805 * mei_cl_dev_setup - setup me client device
 806 *    run fix up routines and set the device name
 807 *
 808 * @bus: mei device
 809 * @cldev: me client device
 810 *
 811 * Return: true if the device is eligible for enumeration
 812 */
 813static bool mei_cl_bus_dev_setup(struct mei_device *bus,
 814                                 struct mei_cl_device *cldev)
 815{
 816        cldev->do_match = 1;
 817        mei_cl_bus_dev_fixup(cldev);
 818
 819        /* the device name can change during fix up */
 820        if (cldev->do_match)
 821                mei_cl_bus_set_name(cldev);
 822
 823        return cldev->do_match == 1;
 824}
 825
 826/**
 827 * mei_cl_bus_dev_add - add me client devices
 828 *
 829 * @cldev: me client device
 830 *
 831 * Return: 0 on success; < 0 on failre
 832 */
 833static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
 834{
 835        int ret;
 836
 837        dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
 838                mei_me_cl_uuid(cldev->me_cl),
 839                mei_me_cl_ver(cldev->me_cl));
 840        ret = device_add(&cldev->dev);
 841        if (!ret)
 842                cldev->is_added = 1;
 843
 844        return ret;
 845}
 846
 847/**
 848 * mei_cl_bus_dev_stop - stop the driver
 849 *
 850 * @cldev: me client device
 851 */
 852static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
 853{
 854        if (cldev->is_added)
 855                device_release_driver(&cldev->dev);
 856}
 857
 858/**
 859 * mei_cl_bus_dev_destroy - destroy me client devices object
 860 *
 861 * @cldev: me client device
 862 *
 863 * Locking: called under "dev->cl_bus_lock" lock
 864 */
 865static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
 866{
 867
 868        WARN_ON(!mutex_is_locked(&cldev->bus->cl_bus_lock));
 869
 870        if (!cldev->is_added)
 871                return;
 872
 873        device_del(&cldev->dev);
 874
 875        list_del_init(&cldev->bus_list);
 876
 877        cldev->is_added = 0;
 878        put_device(&cldev->dev);
 879}
 880
 881/**
 882 * mei_cl_bus_remove_device - remove a devices form the bus
 883 *
 884 * @cldev: me client device
 885 */
 886static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
 887{
 888        mei_cl_bus_dev_stop(cldev);
 889        mei_cl_bus_dev_destroy(cldev);
 890}
 891
 892/**
 893 * mei_cl_bus_remove_devices - remove all devices form the bus
 894 *
 895 * @bus: mei device
 896 */
 897void mei_cl_bus_remove_devices(struct mei_device *bus)
 898{
 899        struct mei_cl_device *cldev, *next;
 900
 901        mutex_lock(&bus->cl_bus_lock);
 902        list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
 903                mei_cl_bus_remove_device(cldev);
 904        mutex_unlock(&bus->cl_bus_lock);
 905}
 906
 907
 908/**
 909 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
 910 *     based on me client
 911 *
 912 * @bus: mei device
 913 * @me_cl: me client
 914 *
 915 * Locking: called under "dev->cl_bus_lock" lock
 916 */
 917static void mei_cl_bus_dev_init(struct mei_device *bus,
 918                                struct mei_me_client *me_cl)
 919{
 920        struct mei_cl_device *cldev;
 921
 922        WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));
 923
 924        dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
 925
 926        if (me_cl->bus_added)
 927                return;
 928
 929        cldev = mei_cl_bus_dev_alloc(bus, me_cl);
 930        if (!cldev)
 931                return;
 932
 933        me_cl->bus_added = true;
 934        list_add_tail(&cldev->bus_list, &bus->device_list);
 935
 936}
 937
 938/**
 939 * mei_cl_bus_rescan - scan me clients list and add create
 940 *    devices for eligible clients
 941 *
 942 * @bus: mei device
 943 */
 944void mei_cl_bus_rescan(struct mei_device *bus)
 945{
 946        struct mei_cl_device *cldev, *n;
 947        struct mei_me_client *me_cl;
 948
 949        mutex_lock(&bus->cl_bus_lock);
 950
 951        down_read(&bus->me_clients_rwsem);
 952        list_for_each_entry(me_cl, &bus->me_clients, list)
 953                mei_cl_bus_dev_init(bus, me_cl);
 954        up_read(&bus->me_clients_rwsem);
 955
 956        list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
 957
 958                if (!mei_me_cl_is_active(cldev->me_cl)) {
 959                        mei_cl_bus_remove_device(cldev);
 960                        continue;
 961                }
 962
 963                if (cldev->is_added)
 964                        continue;
 965
 966                if (mei_cl_bus_dev_setup(bus, cldev))
 967                        mei_cl_bus_dev_add(cldev);
 968                else {
 969                        list_del_init(&cldev->bus_list);
 970                        put_device(&cldev->dev);
 971                }
 972        }
 973        mutex_unlock(&bus->cl_bus_lock);
 974
 975        dev_dbg(bus->dev, "rescan end");
 976}
 977
 978void mei_cl_bus_rescan_work(struct work_struct *work)
 979{
 980        struct mei_device *bus =
 981                container_of(work, struct mei_device, bus_rescan_work);
 982        struct mei_me_client *me_cl;
 983
 984        mutex_lock(&bus->device_lock);
 985        me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
 986        if (me_cl)
 987                mei_amthif_host_init(bus, me_cl);
 988        mei_me_cl_put(me_cl);
 989        mutex_unlock(&bus->device_lock);
 990
 991        mei_cl_bus_rescan(bus);
 992}
 993
 994int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
 995                                struct module *owner)
 996{
 997        int err;
 998
 999        cldrv->driver.name = cldrv->name;
1000        cldrv->driver.owner = owner;
1001        cldrv->driver.bus = &mei_cl_bus_type;
1002
1003        err = driver_register(&cldrv->driver);
1004        if (err)
1005                return err;
1006
1007        pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
1008
1009        return 0;
1010}
1011EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1012
1013void 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}
1019EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1020
1021
1022int __init mei_cl_bus_init(void)
1023{
1024        return bus_register(&mei_cl_bus_type);
1025}
1026
1027void __exit mei_cl_bus_exit(void)
1028{
1029        bus_unregister(&mei_cl_bus_type);
1030}
1031