linux/drivers/misc/mei/bus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2012-2019, Intel Corporation. All rights reserved.
   4 * Intel Management Engine Interface (Intel MEI) Linux driver
   5 */
   6
   7#include <linux/module.h>
   8#include <linux/device.h>
   9#include <linux/kernel.h>
  10#include <linux/sched/signal.h>
  11#include <linux/init.h>
  12#include <linux/errno.h>
  13#include <linux/slab.h>
  14#include <linux/mutex.h>
  15#include <linux/interrupt.h>
  16#include <linux/mei_cl_bus.h>
  17
  18#include "mei_dev.h"
  19#include "client.h"
  20
  21#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
  22
  23/**
  24 * __mei_cl_send - internal client send (write)
  25 *
  26 * @cl: host client
  27 * @buf: buffer to send
  28 * @length: buffer length
  29 * @vtag: virtual tag
  30 * @mode: sending mode
  31 *
  32 * Return: written size bytes or < 0 on error
  33 */
  34ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag,
  35                      unsigned int mode)
  36{
  37        struct mei_device *bus;
  38        struct mei_cl_cb *cb;
  39        ssize_t rets;
  40
  41        if (WARN_ON(!cl || !cl->dev))
  42                return -ENODEV;
  43
  44        bus = cl->dev;
  45
  46        mutex_lock(&bus->device_lock);
  47        if (bus->dev_state != MEI_DEV_ENABLED &&
  48            bus->dev_state != MEI_DEV_POWERING_DOWN) {
  49                rets = -ENODEV;
  50                goto out;
  51        }
  52
  53        if (!mei_cl_is_connected(cl)) {
  54                rets = -ENODEV;
  55                goto out;
  56        }
  57
  58        /* Check if we have an ME client device */
  59        if (!mei_me_cl_is_active(cl->me_cl)) {
  60                rets = -ENOTTY;
  61                goto out;
  62        }
  63
  64        if (vtag) {
  65                /* Check if vtag is supported by client */
  66                rets = mei_cl_vt_support_check(cl);
  67                if (rets)
  68                        goto out;
  69        }
  70
  71        if (length > mei_cl_mtu(cl)) {
  72                rets = -EFBIG;
  73                goto out;
  74        }
  75
  76        while (cl->tx_cb_queued >= bus->tx_queue_limit) {
  77                mutex_unlock(&bus->device_lock);
  78                rets = wait_event_interruptible(cl->tx_wait,
  79                                cl->writing_state == MEI_WRITE_COMPLETE ||
  80                                (!mei_cl_is_connected(cl)));
  81                mutex_lock(&bus->device_lock);
  82                if (rets) {
  83                        if (signal_pending(current))
  84                                rets = -EINTR;
  85                        goto out;
  86                }
  87                if (!mei_cl_is_connected(cl)) {
  88                        rets = -ENODEV;
  89                        goto out;
  90                }
  91        }
  92
  93        cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
  94        if (!cb) {
  95                rets = -ENOMEM;
  96                goto out;
  97        }
  98        cb->vtag = vtag;
  99
 100        cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
 101        cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
 102        memcpy(cb->buf.data, buf, length);
 103
 104        rets = mei_cl_write(cl, cb);
 105
 106out:
 107        mutex_unlock(&bus->device_lock);
 108
 109        return rets;
 110}
 111
 112/**
 113 * __mei_cl_recv - internal client receive (read)
 114 *
 115 * @cl: host client
 116 * @buf: buffer to receive
 117 * @length: buffer length
 118 * @mode: io mode
 119 * @vtag: virtual tag
 120 * @timeout: recv timeout, 0 for infinite timeout
 121 *
 122 * Return: read size in bytes of < 0 on error
 123 */
 124ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag,
 125                      unsigned int mode, unsigned long timeout)
 126{
 127        struct mei_device *bus;
 128        struct mei_cl_cb *cb;
 129        size_t r_length;
 130        ssize_t rets;
 131        bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK);
 132
 133        if (WARN_ON(!cl || !cl->dev))
 134                return -ENODEV;
 135
 136        bus = cl->dev;
 137
 138        mutex_lock(&bus->device_lock);
 139        if (bus->dev_state != MEI_DEV_ENABLED &&
 140            bus->dev_state != MEI_DEV_POWERING_DOWN) {
 141                rets = -ENODEV;
 142                goto out;
 143        }
 144
 145        cb = mei_cl_read_cb(cl, NULL);
 146        if (cb)
 147                goto copy;
 148
 149        rets = mei_cl_read_start(cl, length, NULL);
 150        if (rets && rets != -EBUSY)
 151                goto out;
 152
 153        if (nonblock) {
 154                rets = -EAGAIN;
 155                goto out;
 156        }
 157
 158        /* wait on event only if there is no other waiter */
 159        /* synchronized under device mutex */
 160        if (!waitqueue_active(&cl->rx_wait)) {
 161
 162                mutex_unlock(&bus->device_lock);
 163
 164                if (timeout) {
 165                        rets = wait_event_interruptible_timeout
 166                                        (cl->rx_wait,
 167                                        mei_cl_read_cb(cl, NULL) ||
 168                                        (!mei_cl_is_connected(cl)),
 169                                        msecs_to_jiffies(timeout));
 170                        if (rets == 0)
 171                                return -ETIME;
 172                        if (rets < 0) {
 173                                if (signal_pending(current))
 174                                        return -EINTR;
 175                                return -ERESTARTSYS;
 176                        }
 177                } else {
 178                        if (wait_event_interruptible
 179                                        (cl->rx_wait,
 180                                        mei_cl_read_cb(cl, NULL) ||
 181                                        (!mei_cl_is_connected(cl)))) {
 182                                if (signal_pending(current))
 183                                        return -EINTR;
 184                                return -ERESTARTSYS;
 185                        }
 186                }
 187
 188                mutex_lock(&bus->device_lock);
 189
 190                if (!mei_cl_is_connected(cl)) {
 191                        rets = -ENODEV;
 192                        goto out;
 193                }
 194        }
 195
 196        cb = mei_cl_read_cb(cl, NULL);
 197        if (!cb) {
 198                rets = 0;
 199                goto out;
 200        }
 201
 202copy:
 203        if (cb->status) {
 204                rets = cb->status;
 205                goto free;
 206        }
 207
 208        r_length = min_t(size_t, length, cb->buf_idx);
 209        memcpy(buf, cb->buf.data, r_length);
 210        rets = r_length;
 211        if (vtag)
 212                *vtag = cb->vtag;
 213
 214free:
 215        mei_cl_del_rd_completed(cl, cb);
 216out:
 217        mutex_unlock(&bus->device_lock);
 218
 219        return rets;
 220}
 221
 222/**
 223 * mei_cldev_send_vtag - me device send with vtag  (write)
 224 *
 225 * @cldev: me client device
 226 * @buf: buffer to send
 227 * @length: buffer length
 228 * @vtag: virtual tag
 229 *
 230 * Return:
 231 *  * written size in bytes
 232 *  * < 0 on error
 233 */
 234
 235ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
 236                            u8 vtag)
 237{
 238        struct mei_cl *cl = cldev->cl;
 239
 240        return __mei_cl_send(cl, buf, length, vtag, MEI_CL_IO_TX_BLOCKING);
 241}
 242EXPORT_SYMBOL_GPL(mei_cldev_send_vtag);
 243
 244/**
 245 * mei_cldev_recv_vtag - client receive with vtag (read)
 246 *
 247 * @cldev: me client device
 248 * @buf: buffer to receive
 249 * @length: buffer length
 250 * @vtag: virtual tag
 251 *
 252 * Return:
 253 * * read size in bytes
 254 * *  < 0 on error
 255 */
 256
 257ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
 258                            u8 *vtag)
 259{
 260        struct mei_cl *cl = cldev->cl;
 261
 262        return __mei_cl_recv(cl, buf, length, vtag, 0, 0);
 263}
 264EXPORT_SYMBOL_GPL(mei_cldev_recv_vtag);
 265
 266/**
 267 * mei_cldev_recv_nonblock_vtag - non block client receive with vtag (read)
 268 *
 269 * @cldev: me client device
 270 * @buf: buffer to receive
 271 * @length: buffer length
 272 * @vtag: virtual tag
 273 *
 274 * Return:
 275 * * read size in bytes
 276 * * -EAGAIN if function will block.
 277 * * < 0 on other error
 278 */
 279ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf,
 280                                     size_t length, u8 *vtag)
 281{
 282        struct mei_cl *cl = cldev->cl;
 283
 284        return __mei_cl_recv(cl, buf, length, vtag, MEI_CL_IO_RX_NONBLOCK, 0);
 285}
 286EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock_vtag);
 287
 288/**
 289 * mei_cldev_send - me device send  (write)
 290 *
 291 * @cldev: me client device
 292 * @buf: buffer to send
 293 * @length: buffer length
 294 *
 295 * Return:
 296 *  * written size in bytes
 297 *  * < 0 on error
 298 */
 299ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 300{
 301        return mei_cldev_send_vtag(cldev, buf, length, 0);
 302}
 303EXPORT_SYMBOL_GPL(mei_cldev_send);
 304
 305/**
 306 * mei_cldev_recv - client receive (read)
 307 *
 308 * @cldev: me client device
 309 * @buf: buffer to receive
 310 * @length: buffer length
 311 *
 312 * Return: read size in bytes of < 0 on error
 313 */
 314ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
 315{
 316        return mei_cldev_recv_vtag(cldev, buf, length, NULL);
 317}
 318EXPORT_SYMBOL_GPL(mei_cldev_recv);
 319
 320/**
 321 * mei_cldev_recv_nonblock - non block client receive (read)
 322 *
 323 * @cldev: me client device
 324 * @buf: buffer to receive
 325 * @length: buffer length
 326 *
 327 * Return: read size in bytes of < 0 on error
 328 *         -EAGAIN if function will block.
 329 */
 330ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
 331                                size_t length)
 332{
 333        return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL);
 334}
 335EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
 336
 337/**
 338 * mei_cl_bus_rx_work - dispatch rx event for a bus device
 339 *
 340 * @work: work
 341 */
 342static void mei_cl_bus_rx_work(struct work_struct *work)
 343{
 344        struct mei_cl_device *cldev;
 345        struct mei_device *bus;
 346
 347        cldev = container_of(work, struct mei_cl_device, rx_work);
 348
 349        bus = cldev->bus;
 350
 351        if (cldev->rx_cb)
 352                cldev->rx_cb(cldev);
 353
 354        mutex_lock(&bus->device_lock);
 355        if (mei_cl_is_connected(cldev->cl))
 356                mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
 357        mutex_unlock(&bus->device_lock);
 358}
 359
 360/**
 361 * mei_cl_bus_notif_work - dispatch FW notif event for a bus device
 362 *
 363 * @work: work
 364 */
 365static void mei_cl_bus_notif_work(struct work_struct *work)
 366{
 367        struct mei_cl_device *cldev;
 368
 369        cldev = container_of(work, struct mei_cl_device, notif_work);
 370
 371        if (cldev->notif_cb)
 372                cldev->notif_cb(cldev);
 373}
 374
 375/**
 376 * mei_cl_bus_notify_event - schedule notify cb on bus client
 377 *
 378 * @cl: host client
 379 *
 380 * Return: true if event was scheduled
 381 *         false if the client is not waiting for event
 382 */
 383bool mei_cl_bus_notify_event(struct mei_cl *cl)
 384{
 385        struct mei_cl_device *cldev = cl->cldev;
 386
 387        if (!cldev || !cldev->notif_cb)
 388                return false;
 389
 390        if (!cl->notify_ev)
 391                return false;
 392
 393        schedule_work(&cldev->notif_work);
 394
 395        cl->notify_ev = false;
 396
 397        return true;
 398}
 399
 400/**
 401 * mei_cl_bus_rx_event - schedule rx event
 402 *
 403 * @cl: host client
 404 *
 405 * Return: true if event was scheduled
 406 *         false if the client is not waiting for event
 407 */
 408bool mei_cl_bus_rx_event(struct mei_cl *cl)
 409{
 410        struct mei_cl_device *cldev = cl->cldev;
 411
 412        if (!cldev || !cldev->rx_cb)
 413                return false;
 414
 415        schedule_work(&cldev->rx_work);
 416
 417        return true;
 418}
 419
 420/**
 421 * mei_cldev_register_rx_cb - register Rx event callback
 422 *
 423 * @cldev: me client devices
 424 * @rx_cb: callback function
 425 *
 426 * Return: 0 on success
 427 *         -EALREADY if an callback is already registered
 428 *         <0 on other errors
 429 */
 430int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb)
 431{
 432        struct mei_device *bus = cldev->bus;
 433        int ret;
 434
 435        if (!rx_cb)
 436                return -EINVAL;
 437        if (cldev->rx_cb)
 438                return -EALREADY;
 439
 440        cldev->rx_cb = rx_cb;
 441        INIT_WORK(&cldev->rx_work, mei_cl_bus_rx_work);
 442
 443        mutex_lock(&bus->device_lock);
 444        if (mei_cl_is_connected(cldev->cl))
 445                ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
 446        else
 447                ret = -ENODEV;
 448        mutex_unlock(&bus->device_lock);
 449        if (ret && ret != -EBUSY) {
 450                cancel_work_sync(&cldev->rx_work);
 451                cldev->rx_cb = NULL;
 452                return ret;
 453        }
 454
 455        return 0;
 456}
 457EXPORT_SYMBOL_GPL(mei_cldev_register_rx_cb);
 458
 459/**
 460 * mei_cldev_register_notif_cb - register FW notification event callback
 461 *
 462 * @cldev: me client devices
 463 * @notif_cb: callback function
 464 *
 465 * Return: 0 on success
 466 *         -EALREADY if an callback is already registered
 467 *         <0 on other errors
 468 */
 469int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,
 470                                mei_cldev_cb_t notif_cb)
 471{
 472        struct mei_device *bus = cldev->bus;
 473        int ret;
 474
 475        if (!notif_cb)
 476                return -EINVAL;
 477
 478        if (cldev->notif_cb)
 479                return -EALREADY;
 480
 481        cldev->notif_cb = notif_cb;
 482        INIT_WORK(&cldev->notif_work, mei_cl_bus_notif_work);
 483
 484        mutex_lock(&bus->device_lock);
 485        ret = mei_cl_notify_request(cldev->cl, NULL, 1);
 486        mutex_unlock(&bus->device_lock);
 487        if (ret) {
 488                cancel_work_sync(&cldev->notif_work);
 489                cldev->notif_cb = NULL;
 490                return ret;
 491        }
 492
 493        return 0;
 494}
 495EXPORT_SYMBOL_GPL(mei_cldev_register_notif_cb);
 496
 497/**
 498 * mei_cldev_get_drvdata - driver data getter
 499 *
 500 * @cldev: mei client device
 501 *
 502 * Return: driver private data
 503 */
 504void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
 505{
 506        return dev_get_drvdata(&cldev->dev);
 507}
 508EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
 509
 510/**
 511 * mei_cldev_set_drvdata - driver data setter
 512 *
 513 * @cldev: mei client device
 514 * @data: data to store
 515 */
 516void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
 517{
 518        dev_set_drvdata(&cldev->dev, data);
 519}
 520EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
 521
 522/**
 523 * mei_cldev_uuid - return uuid of the underlying me client
 524 *
 525 * @cldev: mei client device
 526 *
 527 * Return: me client uuid
 528 */
 529const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
 530{
 531        return mei_me_cl_uuid(cldev->me_cl);
 532}
 533EXPORT_SYMBOL_GPL(mei_cldev_uuid);
 534
 535/**
 536 * mei_cldev_ver - return protocol version of the underlying me client
 537 *
 538 * @cldev: mei client device
 539 *
 540 * Return: me client protocol version
 541 */
 542u8 mei_cldev_ver(const struct mei_cl_device *cldev)
 543{
 544        return mei_me_cl_ver(cldev->me_cl);
 545}
 546EXPORT_SYMBOL_GPL(mei_cldev_ver);
 547
 548/**
 549 * mei_cldev_enabled - check whether the device is enabled
 550 *
 551 * @cldev: mei client device
 552 *
 553 * Return: true if me client is initialized and connected
 554 */
 555bool mei_cldev_enabled(struct mei_cl_device *cldev)
 556{
 557        return mei_cl_is_connected(cldev->cl);
 558}
 559EXPORT_SYMBOL_GPL(mei_cldev_enabled);
 560
 561/**
 562 * mei_cl_bus_module_get - acquire module of the underlying
 563 *    hw driver.
 564 *
 565 * @cldev: mei client device
 566 *
 567 * Return: true on success; false if the module was removed.
 568 */
 569static bool mei_cl_bus_module_get(struct mei_cl_device *cldev)
 570{
 571        return try_module_get(cldev->bus->dev->driver->owner);
 572}
 573
 574/**
 575 * mei_cl_bus_module_put -  release the underlying hw module.
 576 *
 577 * @cldev: mei client device
 578 */
 579static void mei_cl_bus_module_put(struct mei_cl_device *cldev)
 580{
 581        module_put(cldev->bus->dev->driver->owner);
 582}
 583
 584/**
 585 * mei_cl_bus_vtag - get bus vtag entry wrapper
 586 *     The tag for bus client is always first.
 587 *
 588 * @cl: host client
 589 *
 590 * Return: bus vtag or NULL
 591 */
 592static inline struct mei_cl_vtag *mei_cl_bus_vtag(struct mei_cl *cl)
 593{
 594        return list_first_entry_or_null(&cl->vtag_map,
 595                                        struct mei_cl_vtag, list);
 596}
 597
 598/**
 599 * mei_cl_bus_vtag_alloc - add bus client entry to vtag map
 600 *
 601 * @cldev: me client device
 602 *
 603 * Return:
 604 * * 0 on success
 605 * * -ENOMEM if memory allocation failed
 606 */
 607static int mei_cl_bus_vtag_alloc(struct mei_cl_device *cldev)
 608{
 609        struct mei_cl *cl = cldev->cl;
 610        struct mei_cl_vtag *cl_vtag;
 611
 612        /*
 613         * Bail out if the client does not supports vtags
 614         * or has already allocated one
 615         */
 616        if (mei_cl_vt_support_check(cl) || mei_cl_bus_vtag(cl))
 617                return 0;
 618
 619        cl_vtag = mei_cl_vtag_alloc(NULL, 0);
 620        if (IS_ERR(cl_vtag))
 621                return -ENOMEM;
 622
 623        list_add_tail(&cl_vtag->list, &cl->vtag_map);
 624
 625        return 0;
 626}
 627
 628/**
 629 * mei_cl_bus_vtag_free - remove the bus entry from vtag map
 630 *
 631 * @cldev: me client device
 632 */
 633static void mei_cl_bus_vtag_free(struct mei_cl_device *cldev)
 634{
 635        struct mei_cl *cl = cldev->cl;
 636        struct mei_cl_vtag *cl_vtag;
 637
 638        cl_vtag = mei_cl_bus_vtag(cl);
 639        if (!cl_vtag)
 640                return;
 641
 642        list_del(&cl_vtag->list);
 643        kfree(cl_vtag);
 644}
 645
 646/**
 647 * mei_cldev_enable - enable me client device
 648 *     create connection with me client
 649 *
 650 * @cldev: me client device
 651 *
 652 * Return: 0 on success and < 0 on error
 653 */
 654int mei_cldev_enable(struct mei_cl_device *cldev)
 655{
 656        struct mei_device *bus = cldev->bus;
 657        struct mei_cl *cl;
 658        int ret;
 659
 660        cl = cldev->cl;
 661
 662        mutex_lock(&bus->device_lock);
 663        if (cl->state == MEI_FILE_UNINITIALIZED) {
 664                ret = mei_cl_link(cl);
 665                if (ret)
 666                        goto out;
 667                /* update pointers */
 668                cl->cldev = cldev;
 669        }
 670
 671        if (mei_cl_is_connected(cl)) {
 672                ret = 0;
 673                goto out;
 674        }
 675
 676        if (!mei_me_cl_is_active(cldev->me_cl)) {
 677                dev_err(&cldev->dev, "me client is not active\n");
 678                ret = -ENOTTY;
 679                goto out;
 680        }
 681
 682        ret = mei_cl_bus_vtag_alloc(cldev);
 683        if (ret)
 684                goto out;
 685
 686        ret = mei_cl_connect(cl, cldev->me_cl, NULL);
 687        if (ret < 0) {
 688                dev_err(&cldev->dev, "cannot connect\n");
 689                mei_cl_bus_vtag_free(cldev);
 690        }
 691
 692out:
 693        mutex_unlock(&bus->device_lock);
 694
 695        return ret;
 696}
 697EXPORT_SYMBOL_GPL(mei_cldev_enable);
 698
 699/**
 700 * mei_cldev_unregister_callbacks - internal wrapper for unregistering
 701 *  callbacks.
 702 *
 703 * @cldev: client device
 704 */
 705static void mei_cldev_unregister_callbacks(struct mei_cl_device *cldev)
 706{
 707        if (cldev->rx_cb) {
 708                cancel_work_sync(&cldev->rx_work);
 709                cldev->rx_cb = NULL;
 710        }
 711
 712        if (cldev->notif_cb) {
 713                cancel_work_sync(&cldev->notif_work);
 714                cldev->notif_cb = NULL;
 715        }
 716}
 717
 718/**
 719 * mei_cldev_disable - disable me client device
 720 *     disconnect form the me client
 721 *
 722 * @cldev: me client device
 723 *
 724 * Return: 0 on success and < 0 on error
 725 */
 726int mei_cldev_disable(struct mei_cl_device *cldev)
 727{
 728        struct mei_device *bus;
 729        struct mei_cl *cl;
 730        int err;
 731
 732        if (!cldev)
 733                return -ENODEV;
 734
 735        cl = cldev->cl;
 736
 737        bus = cldev->bus;
 738
 739        mei_cldev_unregister_callbacks(cldev);
 740
 741        mutex_lock(&bus->device_lock);
 742
 743        mei_cl_bus_vtag_free(cldev);
 744
 745        if (!mei_cl_is_connected(cl)) {
 746                dev_dbg(bus->dev, "Already disconnected\n");
 747                err = 0;
 748                goto out;
 749        }
 750
 751        err = mei_cl_disconnect(cl);
 752        if (err < 0)
 753                dev_err(bus->dev, "Could not disconnect from the ME client\n");
 754
 755out:
 756        /* Flush queues and remove any pending read */
 757        mei_cl_flush_queues(cl, NULL);
 758        mei_cl_unlink(cl);
 759
 760        mutex_unlock(&bus->device_lock);
 761        return err;
 762}
 763EXPORT_SYMBOL_GPL(mei_cldev_disable);
 764
 765/**
 766 * mei_cl_device_find - find matching entry in the driver id table
 767 *
 768 * @cldev: me client device
 769 * @cldrv: me client driver
 770 *
 771 * Return: id on success; NULL if no id is matching
 772 */
 773static const
 774struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
 775                                            struct mei_cl_driver *cldrv)
 776{
 777        const struct mei_cl_device_id *id;
 778        const uuid_le *uuid;
 779        u8 version;
 780        bool match;
 781
 782        uuid = mei_me_cl_uuid(cldev->me_cl);
 783        version = mei_me_cl_ver(cldev->me_cl);
 784
 785        id = cldrv->id_table;
 786        while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
 787                if (!uuid_le_cmp(*uuid, id->uuid)) {
 788                        match = true;
 789
 790                        if (cldev->name[0])
 791                                if (strncmp(cldev->name, id->name,
 792                                            sizeof(id->name)))
 793                                        match = false;
 794
 795                        if (id->version != MEI_CL_VERSION_ANY)
 796                                if (id->version != version)
 797                                        match = false;
 798                        if (match)
 799                                return id;
 800                }
 801
 802                id++;
 803        }
 804
 805        return NULL;
 806}
 807
 808/**
 809 * mei_cl_device_match  - device match function
 810 *
 811 * @dev: device
 812 * @drv: driver
 813 *
 814 * Return:  1 if matching device was found 0 otherwise
 815 */
 816static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
 817{
 818        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 819        struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
 820        const struct mei_cl_device_id *found_id;
 821
 822        if (!cldev)
 823                return 0;
 824
 825        if (!cldev->do_match)
 826                return 0;
 827
 828        if (!cldrv || !cldrv->id_table)
 829                return 0;
 830
 831        found_id = mei_cl_device_find(cldev, cldrv);
 832        if (found_id)
 833                return 1;
 834
 835        return 0;
 836}
 837
 838/**
 839 * mei_cl_device_probe - bus probe function
 840 *
 841 * @dev: device
 842 *
 843 * Return:  0 on success; < 0 otherwise
 844 */
 845static int mei_cl_device_probe(struct device *dev)
 846{
 847        struct mei_cl_device *cldev;
 848        struct mei_cl_driver *cldrv;
 849        const struct mei_cl_device_id *id;
 850        int ret;
 851
 852        cldev = to_mei_cl_device(dev);
 853        cldrv = to_mei_cl_driver(dev->driver);
 854
 855        if (!cldev)
 856                return 0;
 857
 858        if (!cldrv || !cldrv->probe)
 859                return -ENODEV;
 860
 861        id = mei_cl_device_find(cldev, cldrv);
 862        if (!id)
 863                return -ENODEV;
 864
 865        if (!mei_cl_bus_module_get(cldev)) {
 866                dev_err(&cldev->dev, "get hw module failed");
 867                return -ENODEV;
 868        }
 869
 870        ret = cldrv->probe(cldev, id);
 871        if (ret) {
 872                mei_cl_bus_module_put(cldev);
 873                return ret;
 874        }
 875
 876        __module_get(THIS_MODULE);
 877        return 0;
 878}
 879
 880/**
 881 * mei_cl_device_remove - remove device from the bus
 882 *
 883 * @dev: device
 884 *
 885 * Return:  0 on success; < 0 otherwise
 886 */
 887static int mei_cl_device_remove(struct device *dev)
 888{
 889        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 890        struct mei_cl_driver *cldrv = to_mei_cl_driver(dev->driver);
 891
 892        if (cldrv->remove)
 893                cldrv->remove(cldev);
 894
 895        mei_cldev_unregister_callbacks(cldev);
 896
 897        mei_cl_bus_module_put(cldev);
 898        module_put(THIS_MODULE);
 899
 900        return 0;
 901}
 902
 903static ssize_t name_show(struct device *dev, struct device_attribute *a,
 904                             char *buf)
 905{
 906        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 907
 908        return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
 909}
 910static DEVICE_ATTR_RO(name);
 911
 912static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
 913                             char *buf)
 914{
 915        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 916        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 917
 918        return sprintf(buf, "%pUl", uuid);
 919}
 920static DEVICE_ATTR_RO(uuid);
 921
 922static ssize_t version_show(struct device *dev, struct device_attribute *a,
 923                             char *buf)
 924{
 925        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 926        u8 version = mei_me_cl_ver(cldev->me_cl);
 927
 928        return sprintf(buf, "%02X", version);
 929}
 930static DEVICE_ATTR_RO(version);
 931
 932static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 933                             char *buf)
 934{
 935        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 936        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
 937        u8 version = mei_me_cl_ver(cldev->me_cl);
 938
 939        return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:%02X:",
 940                         cldev->name, uuid, version);
 941}
 942static DEVICE_ATTR_RO(modalias);
 943
 944static ssize_t max_conn_show(struct device *dev, struct device_attribute *a,
 945                             char *buf)
 946{
 947        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 948        u8 maxconn = mei_me_cl_max_conn(cldev->me_cl);
 949
 950        return sprintf(buf, "%d", maxconn);
 951}
 952static DEVICE_ATTR_RO(max_conn);
 953
 954static ssize_t fixed_show(struct device *dev, struct device_attribute *a,
 955                          char *buf)
 956{
 957        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 958        u8 fixed = mei_me_cl_fixed(cldev->me_cl);
 959
 960        return sprintf(buf, "%d", fixed);
 961}
 962static DEVICE_ATTR_RO(fixed);
 963
 964static ssize_t vtag_show(struct device *dev, struct device_attribute *a,
 965                         char *buf)
 966{
 967        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 968        bool vt = mei_me_cl_vt(cldev->me_cl);
 969
 970        return sprintf(buf, "%d", vt);
 971}
 972static DEVICE_ATTR_RO(vtag);
 973
 974static ssize_t max_len_show(struct device *dev, struct device_attribute *a,
 975                            char *buf)
 976{
 977        struct mei_cl_device *cldev = to_mei_cl_device(dev);
 978        u32 maxlen = mei_me_cl_max_len(cldev->me_cl);
 979
 980        return sprintf(buf, "%u", maxlen);
 981}
 982static DEVICE_ATTR_RO(max_len);
 983
 984static struct attribute *mei_cldev_attrs[] = {
 985        &dev_attr_name.attr,
 986        &dev_attr_uuid.attr,
 987        &dev_attr_version.attr,
 988        &dev_attr_modalias.attr,
 989        &dev_attr_max_conn.attr,
 990        &dev_attr_fixed.attr,
 991        &dev_attr_vtag.attr,
 992        &dev_attr_max_len.attr,
 993        NULL,
 994};
 995ATTRIBUTE_GROUPS(mei_cldev);
 996
 997/**
 998 * mei_cl_device_uevent - me client bus uevent handler
 999 *
1000 * @dev: device
1001 * @env: uevent kobject
1002 *
1003 * Return: 0 on success -ENOMEM on when add_uevent_var fails
1004 */
1005static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
1006{
1007        struct mei_cl_device *cldev = to_mei_cl_device(dev);
1008        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
1009        u8 version = mei_me_cl_ver(cldev->me_cl);
1010
1011        if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
1012                return -ENOMEM;
1013
1014        if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
1015                return -ENOMEM;
1016
1017        if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
1018                return -ENOMEM;
1019
1020        if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
1021                           cldev->name, uuid, version))
1022                return -ENOMEM;
1023
1024        return 0;
1025}
1026
1027static struct bus_type mei_cl_bus_type = {
1028        .name           = "mei",
1029        .dev_groups     = mei_cldev_groups,
1030        .match          = mei_cl_device_match,
1031        .probe          = mei_cl_device_probe,
1032        .remove         = mei_cl_device_remove,
1033        .uevent         = mei_cl_device_uevent,
1034};
1035
1036static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
1037{
1038        if (bus)
1039                get_device(bus->dev);
1040
1041        return bus;
1042}
1043
1044static void mei_dev_bus_put(struct mei_device *bus)
1045{
1046        if (bus)
1047                put_device(bus->dev);
1048}
1049
1050static void mei_cl_bus_dev_release(struct device *dev)
1051{
1052        struct mei_cl_device *cldev = to_mei_cl_device(dev);
1053
1054        if (!cldev)
1055                return;
1056
1057        mei_me_cl_put(cldev->me_cl);
1058        mei_dev_bus_put(cldev->bus);
1059        mei_cl_unlink(cldev->cl);
1060        kfree(cldev->cl);
1061        kfree(cldev);
1062}
1063
1064static const struct device_type mei_cl_device_type = {
1065        .release = mei_cl_bus_dev_release,
1066};
1067
1068/**
1069 * mei_cl_bus_set_name - set device name for me client device
1070 *  <controller>-<client device>
1071 *  Example: 0000:00:16.0-55213584-9a29-4916-badf-0fb7ed682aeb
1072 *
1073 * @cldev: me client device
1074 */
1075static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
1076{
1077        dev_set_name(&cldev->dev, "%s-%pUl",
1078                     dev_name(cldev->bus->dev),
1079                     mei_me_cl_uuid(cldev->me_cl));
1080}
1081
1082/**
1083 * mei_cl_bus_dev_alloc - initialize and allocate mei client device
1084 *
1085 * @bus: mei device
1086 * @me_cl: me client
1087 *
1088 * Return: allocated device structur or NULL on allocation failure
1089 */
1090static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
1091                                                  struct mei_me_client *me_cl)
1092{
1093        struct mei_cl_device *cldev;
1094        struct mei_cl *cl;
1095
1096        cldev = kzalloc(sizeof(*cldev), GFP_KERNEL);
1097        if (!cldev)
1098                return NULL;
1099
1100        cl = mei_cl_allocate(bus);
1101        if (!cl) {
1102                kfree(cldev);
1103                return NULL;
1104        }
1105
1106        device_initialize(&cldev->dev);
1107        cldev->dev.parent = bus->dev;
1108        cldev->dev.bus    = &mei_cl_bus_type;
1109        cldev->dev.type   = &mei_cl_device_type;
1110        cldev->bus        = mei_dev_bus_get(bus);
1111        cldev->me_cl      = mei_me_cl_get(me_cl);
1112        cldev->cl         = cl;
1113        mei_cl_bus_set_name(cldev);
1114        cldev->is_added   = 0;
1115        INIT_LIST_HEAD(&cldev->bus_list);
1116
1117        return cldev;
1118}
1119
1120/**
1121 * mei_cl_bus_dev_setup - setup me client device
1122 *    run fix up routines and set the device name
1123 *
1124 * @bus: mei device
1125 * @cldev: me client device
1126 *
1127 * Return: true if the device is eligible for enumeration
1128 */
1129static bool mei_cl_bus_dev_setup(struct mei_device *bus,
1130                                 struct mei_cl_device *cldev)
1131{
1132        cldev->do_match = 1;
1133        mei_cl_bus_dev_fixup(cldev);
1134
1135        /* the device name can change during fix up */
1136        if (cldev->do_match)
1137                mei_cl_bus_set_name(cldev);
1138
1139        return cldev->do_match == 1;
1140}
1141
1142/**
1143 * mei_cl_bus_dev_add - add me client devices
1144 *
1145 * @cldev: me client device
1146 *
1147 * Return: 0 on success; < 0 on failre
1148 */
1149static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
1150{
1151        int ret;
1152
1153        dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
1154                mei_me_cl_uuid(cldev->me_cl),
1155                mei_me_cl_ver(cldev->me_cl));
1156        ret = device_add(&cldev->dev);
1157        if (!ret)
1158                cldev->is_added = 1;
1159
1160        return ret;
1161}
1162
1163/**
1164 * mei_cl_bus_dev_stop - stop the driver
1165 *
1166 * @cldev: me client device
1167 */
1168static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
1169{
1170        if (cldev->is_added)
1171                device_release_driver(&cldev->dev);
1172}
1173
1174/**
1175 * mei_cl_bus_dev_destroy - destroy me client devices object
1176 *
1177 * @cldev: me client device
1178 *
1179 * Locking: called under "dev->cl_bus_lock" lock
1180 */
1181static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
1182{
1183
1184        WARN_ON(!mutex_is_locked(&cldev->bus->cl_bus_lock));
1185
1186        if (!cldev->is_added)
1187                return;
1188
1189        device_del(&cldev->dev);
1190
1191        list_del_init(&cldev->bus_list);
1192
1193        cldev->is_added = 0;
1194        put_device(&cldev->dev);
1195}
1196
1197/**
1198 * mei_cl_bus_remove_device - remove a devices form the bus
1199 *
1200 * @cldev: me client device
1201 */
1202static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
1203{
1204        mei_cl_bus_dev_stop(cldev);
1205        mei_cl_bus_dev_destroy(cldev);
1206}
1207
1208/**
1209 * mei_cl_bus_remove_devices - remove all devices form the bus
1210 *
1211 * @bus: mei device
1212 */
1213void mei_cl_bus_remove_devices(struct mei_device *bus)
1214{
1215        struct mei_cl_device *cldev, *next;
1216
1217        mutex_lock(&bus->cl_bus_lock);
1218        list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
1219                mei_cl_bus_remove_device(cldev);
1220        mutex_unlock(&bus->cl_bus_lock);
1221}
1222
1223
1224/**
1225 * mei_cl_bus_dev_init - allocate and initializes an mei client devices
1226 *     based on me client
1227 *
1228 * @bus: mei device
1229 * @me_cl: me client
1230 *
1231 * Locking: called under "dev->cl_bus_lock" lock
1232 */
1233static void mei_cl_bus_dev_init(struct mei_device *bus,
1234                                struct mei_me_client *me_cl)
1235{
1236        struct mei_cl_device *cldev;
1237
1238        WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));
1239
1240        dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
1241
1242        if (me_cl->bus_added)
1243                return;
1244
1245        cldev = mei_cl_bus_dev_alloc(bus, me_cl);
1246        if (!cldev)
1247                return;
1248
1249        me_cl->bus_added = true;
1250        list_add_tail(&cldev->bus_list, &bus->device_list);
1251
1252}
1253
1254/**
1255 * mei_cl_bus_rescan - scan me clients list and add create
1256 *    devices for eligible clients
1257 *
1258 * @bus: mei device
1259 */
1260static void mei_cl_bus_rescan(struct mei_device *bus)
1261{
1262        struct mei_cl_device *cldev, *n;
1263        struct mei_me_client *me_cl;
1264
1265        mutex_lock(&bus->cl_bus_lock);
1266
1267        down_read(&bus->me_clients_rwsem);
1268        list_for_each_entry(me_cl, &bus->me_clients, list)
1269                mei_cl_bus_dev_init(bus, me_cl);
1270        up_read(&bus->me_clients_rwsem);
1271
1272        list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
1273
1274                if (!mei_me_cl_is_active(cldev->me_cl)) {
1275                        mei_cl_bus_remove_device(cldev);
1276                        continue;
1277                }
1278
1279                if (cldev->is_added)
1280                        continue;
1281
1282                if (mei_cl_bus_dev_setup(bus, cldev))
1283                        mei_cl_bus_dev_add(cldev);
1284                else {
1285                        list_del_init(&cldev->bus_list);
1286                        put_device(&cldev->dev);
1287                }
1288        }
1289        mutex_unlock(&bus->cl_bus_lock);
1290
1291        dev_dbg(bus->dev, "rescan end");
1292}
1293
1294void mei_cl_bus_rescan_work(struct work_struct *work)
1295{
1296        struct mei_device *bus =
1297                container_of(work, struct mei_device, bus_rescan_work);
1298
1299        mei_cl_bus_rescan(bus);
1300}
1301
1302int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
1303                                struct module *owner)
1304{
1305        int err;
1306
1307        cldrv->driver.name = cldrv->name;
1308        cldrv->driver.owner = owner;
1309        cldrv->driver.bus = &mei_cl_bus_type;
1310
1311        err = driver_register(&cldrv->driver);
1312        if (err)
1313                return err;
1314
1315        pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
1316
1317        return 0;
1318}
1319EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1320
1321void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1322{
1323        driver_unregister(&cldrv->driver);
1324
1325        pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1326}
1327EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1328
1329
1330int __init mei_cl_bus_init(void)
1331{
1332        return bus_register(&mei_cl_bus_type);
1333}
1334
1335void __exit mei_cl_bus_exit(void)
1336{
1337        bus_unregister(&mei_cl_bus_type);
1338}
1339