linux/drivers/misc/mei/client.c
<<
>>
Prefs
   1/*
   2 *
   3 * Intel Management Engine Interface (Intel MEI) Linux driver
   4 * Copyright (c) 2003-2012, Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 */
  16
  17#include <linux/sched.h>
  18#include <linux/wait.h>
  19#include <linux/delay.h>
  20#include <linux/slab.h>
  21#include <linux/pm_runtime.h>
  22
  23#include <linux/mei.h>
  24
  25#include "mei_dev.h"
  26#include "hbm.h"
  27#include "client.h"
  28
  29/**
  30 * mei_me_cl_init - initialize me client
  31 *
  32 * @me_cl: me client
  33 */
  34void mei_me_cl_init(struct mei_me_client *me_cl)
  35{
  36        INIT_LIST_HEAD(&me_cl->list);
  37        kref_init(&me_cl->refcnt);
  38}
  39
  40/**
  41 * mei_me_cl_get - increases me client refcount
  42 *
  43 * @me_cl: me client
  44 *
  45 * Locking: called under "dev->device_lock" lock
  46 *
  47 * Return: me client or NULL
  48 */
  49struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl)
  50{
  51        if (me_cl && kref_get_unless_zero(&me_cl->refcnt))
  52                return me_cl;
  53
  54        return NULL;
  55}
  56
  57/**
  58 * mei_me_cl_release - free me client
  59 *
  60 * Locking: called under "dev->device_lock" lock
  61 *
  62 * @ref: me_client refcount
  63 */
  64static void mei_me_cl_release(struct kref *ref)
  65{
  66        struct mei_me_client *me_cl =
  67                container_of(ref, struct mei_me_client, refcnt);
  68
  69        kfree(me_cl);
  70}
  71
  72/**
  73 * mei_me_cl_put - decrease me client refcount and free client if necessary
  74 *
  75 * Locking: called under "dev->device_lock" lock
  76 *
  77 * @me_cl: me client
  78 */
  79void mei_me_cl_put(struct mei_me_client *me_cl)
  80{
  81        if (me_cl)
  82                kref_put(&me_cl->refcnt, mei_me_cl_release);
  83}
  84
  85/**
  86 * __mei_me_cl_del  - delete me client from the list and decrease
  87 *     reference counter
  88 *
  89 * @dev: mei device
  90 * @me_cl: me client
  91 *
  92 * Locking: dev->me_clients_rwsem
  93 */
  94static void __mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl)
  95{
  96        if (!me_cl)
  97                return;
  98
  99        list_del_init(&me_cl->list);
 100        mei_me_cl_put(me_cl);
 101}
 102
 103/**
 104 * mei_me_cl_del - delete me client from the list and decrease
 105 *     reference counter
 106 *
 107 * @dev: mei device
 108 * @me_cl: me client
 109 */
 110void mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl)
 111{
 112        down_write(&dev->me_clients_rwsem);
 113        __mei_me_cl_del(dev, me_cl);
 114        up_write(&dev->me_clients_rwsem);
 115}
 116
 117/**
 118 * mei_me_cl_add - add me client to the list
 119 *
 120 * @dev: mei device
 121 * @me_cl: me client
 122 */
 123void mei_me_cl_add(struct mei_device *dev, struct mei_me_client *me_cl)
 124{
 125        down_write(&dev->me_clients_rwsem);
 126        list_add(&me_cl->list, &dev->me_clients);
 127        up_write(&dev->me_clients_rwsem);
 128}
 129
 130/**
 131 * __mei_me_cl_by_uuid - locate me client by uuid
 132 *      increases ref count
 133 *
 134 * @dev: mei device
 135 * @uuid: me client uuid
 136 *
 137 * Return: me client or NULL if not found
 138 *
 139 * Locking: dev->me_clients_rwsem
 140 */
 141static struct mei_me_client *__mei_me_cl_by_uuid(struct mei_device *dev,
 142                                        const uuid_le *uuid)
 143{
 144        struct mei_me_client *me_cl;
 145        const uuid_le *pn;
 146
 147        WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem));
 148
 149        list_for_each_entry(me_cl, &dev->me_clients, list) {
 150                pn = &me_cl->props.protocol_name;
 151                if (uuid_le_cmp(*uuid, *pn) == 0)
 152                        return mei_me_cl_get(me_cl);
 153        }
 154
 155        return NULL;
 156}
 157
 158/**
 159 * mei_me_cl_by_uuid - locate me client by uuid
 160 *      increases ref count
 161 *
 162 * @dev: mei device
 163 * @uuid: me client uuid
 164 *
 165 * Return: me client or NULL if not found
 166 *
 167 * Locking: dev->me_clients_rwsem
 168 */
 169struct mei_me_client *mei_me_cl_by_uuid(struct mei_device *dev,
 170                                        const uuid_le *uuid)
 171{
 172        struct mei_me_client *me_cl;
 173
 174        down_read(&dev->me_clients_rwsem);
 175        me_cl = __mei_me_cl_by_uuid(dev, uuid);
 176        up_read(&dev->me_clients_rwsem);
 177
 178        return me_cl;
 179}
 180
 181/**
 182 * mei_me_cl_by_id - locate me client by client id
 183 *      increases ref count
 184 *
 185 * @dev: the device structure
 186 * @client_id: me client id
 187 *
 188 * Return: me client or NULL if not found
 189 *
 190 * Locking: dev->me_clients_rwsem
 191 */
 192struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
 193{
 194
 195        struct mei_me_client *__me_cl, *me_cl = NULL;
 196
 197        down_read(&dev->me_clients_rwsem);
 198        list_for_each_entry(__me_cl, &dev->me_clients, list) {
 199                if (__me_cl->client_id == client_id) {
 200                        me_cl = mei_me_cl_get(__me_cl);
 201                        break;
 202                }
 203        }
 204        up_read(&dev->me_clients_rwsem);
 205
 206        return me_cl;
 207}
 208
 209/**
 210 * __mei_me_cl_by_uuid_id - locate me client by client id and uuid
 211 *      increases ref count
 212 *
 213 * @dev: the device structure
 214 * @uuid: me client uuid
 215 * @client_id: me client id
 216 *
 217 * Return: me client or null if not found
 218 *
 219 * Locking: dev->me_clients_rwsem
 220 */
 221static struct mei_me_client *__mei_me_cl_by_uuid_id(struct mei_device *dev,
 222                                           const uuid_le *uuid, u8 client_id)
 223{
 224        struct mei_me_client *me_cl;
 225        const uuid_le *pn;
 226
 227        WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem));
 228
 229        list_for_each_entry(me_cl, &dev->me_clients, list) {
 230                pn = &me_cl->props.protocol_name;
 231                if (uuid_le_cmp(*uuid, *pn) == 0 &&
 232                    me_cl->client_id == client_id)
 233                        return mei_me_cl_get(me_cl);
 234        }
 235
 236        return NULL;
 237}
 238
 239
 240/**
 241 * mei_me_cl_by_uuid_id - locate me client by client id and uuid
 242 *      increases ref count
 243 *
 244 * @dev: the device structure
 245 * @uuid: me client uuid
 246 * @client_id: me client id
 247 *
 248 * Return: me client or null if not found
 249 */
 250struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
 251                                           const uuid_le *uuid, u8 client_id)
 252{
 253        struct mei_me_client *me_cl;
 254
 255        down_read(&dev->me_clients_rwsem);
 256        me_cl = __mei_me_cl_by_uuid_id(dev, uuid, client_id);
 257        up_read(&dev->me_clients_rwsem);
 258
 259        return me_cl;
 260}
 261
 262/**
 263 * mei_me_cl_rm_by_uuid - remove all me clients matching uuid
 264 *
 265 * @dev: the device structure
 266 * @uuid: me client uuid
 267 *
 268 * Locking: called under "dev->device_lock" lock
 269 */
 270void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid)
 271{
 272        struct mei_me_client *me_cl;
 273
 274        dev_dbg(dev->dev, "remove %pUl\n", uuid);
 275
 276        down_write(&dev->me_clients_rwsem);
 277        me_cl = __mei_me_cl_by_uuid(dev, uuid);
 278        __mei_me_cl_del(dev, me_cl);
 279        up_write(&dev->me_clients_rwsem);
 280}
 281
 282/**
 283 * mei_me_cl_rm_by_uuid_id - remove all me clients matching client id
 284 *
 285 * @dev: the device structure
 286 * @uuid: me client uuid
 287 * @id: me client id
 288 *
 289 * Locking: called under "dev->device_lock" lock
 290 */
 291void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id)
 292{
 293        struct mei_me_client *me_cl;
 294
 295        dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id);
 296
 297        down_write(&dev->me_clients_rwsem);
 298        me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id);
 299        __mei_me_cl_del(dev, me_cl);
 300        up_write(&dev->me_clients_rwsem);
 301}
 302
 303/**
 304 * mei_me_cl_rm_all - remove all me clients
 305 *
 306 * @dev: the device structure
 307 *
 308 * Locking: called under "dev->device_lock" lock
 309 */
 310void mei_me_cl_rm_all(struct mei_device *dev)
 311{
 312        struct mei_me_client *me_cl, *next;
 313
 314        down_write(&dev->me_clients_rwsem);
 315        list_for_each_entry_safe(me_cl, next, &dev->me_clients, list)
 316                __mei_me_cl_del(dev, me_cl);
 317        up_write(&dev->me_clients_rwsem);
 318}
 319
 320/**
 321 * mei_cl_cmp_id - tells if the clients are the same
 322 *
 323 * @cl1: host client 1
 324 * @cl2: host client 2
 325 *
 326 * Return: true  - if the clients has same host and me ids
 327 *         false - otherwise
 328 */
 329static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
 330                                const struct mei_cl *cl2)
 331{
 332        return cl1 && cl2 &&
 333                (cl1->host_client_id == cl2->host_client_id) &&
 334                (mei_cl_me_id(cl1) == mei_cl_me_id(cl2));
 335}
 336
 337/**
 338 * mei_io_cb_free - free mei_cb_private related memory
 339 *
 340 * @cb: mei callback struct
 341 */
 342void mei_io_cb_free(struct mei_cl_cb *cb)
 343{
 344        if (cb == NULL)
 345                return;
 346
 347        list_del(&cb->list);
 348        kfree(cb->buf.data);
 349        kfree(cb);
 350}
 351
 352/**
 353 * mei_io_cb_init - allocate and initialize io callback
 354 *
 355 * @cl: mei client
 356 * @type: operation type
 357 * @fp: pointer to file structure
 358 *
 359 * Return: mei_cl_cb pointer or NULL;
 360 */
 361struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
 362                                 const struct file *fp)
 363{
 364        struct mei_cl_cb *cb;
 365
 366        cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
 367        if (!cb)
 368                return NULL;
 369
 370        INIT_LIST_HEAD(&cb->list);
 371        cb->fp = fp;
 372        cb->cl = cl;
 373        cb->buf_idx = 0;
 374        cb->fop_type = type;
 375        return cb;
 376}
 377
 378/**
 379 * __mei_io_list_flush - removes and frees cbs belonging to cl.
 380 *
 381 * @list:  an instance of our list structure
 382 * @cl:    host client, can be NULL for flushing the whole list
 383 * @free:  whether to free the cbs
 384 */
 385static void __mei_io_list_flush(struct mei_cl_cb *list,
 386                                struct mei_cl *cl, bool free)
 387{
 388        struct mei_cl_cb *cb, *next;
 389
 390        /* enable removing everything if no cl is specified */
 391        list_for_each_entry_safe(cb, next, &list->list, list) {
 392                if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
 393                        list_del_init(&cb->list);
 394                        if (free)
 395                                mei_io_cb_free(cb);
 396                }
 397        }
 398}
 399
 400/**
 401 * mei_io_list_flush - removes list entry belonging to cl.
 402 *
 403 * @list:  An instance of our list structure
 404 * @cl: host client
 405 */
 406void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
 407{
 408        __mei_io_list_flush(list, cl, false);
 409}
 410
 411/**
 412 * mei_io_list_free - removes cb belonging to cl and free them
 413 *
 414 * @list:  An instance of our list structure
 415 * @cl: host client
 416 */
 417static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
 418{
 419        __mei_io_list_flush(list, cl, true);
 420}
 421
 422/**
 423 * mei_io_cb_alloc_buf - allocate callback buffer
 424 *
 425 * @cb: io callback structure
 426 * @length: size of the buffer
 427 *
 428 * Return: 0 on success
 429 *         -EINVAL if cb is NULL
 430 *         -ENOMEM if allocation failed
 431 */
 432int mei_io_cb_alloc_buf(struct mei_cl_cb *cb, size_t length)
 433{
 434        if (!cb)
 435                return -EINVAL;
 436
 437        if (length == 0)
 438                return 0;
 439
 440        cb->buf.data = kmalloc(length, GFP_KERNEL);
 441        if (!cb->buf.data)
 442                return -ENOMEM;
 443        cb->buf.size = length;
 444        return 0;
 445}
 446
 447/**
 448 * mei_cl_alloc_cb - a convenient wrapper for allocating read cb
 449 *
 450 * @cl: host client
 451 * @length: size of the buffer
 452 * @type: operation type
 453 * @fp: associated file pointer (might be NULL)
 454 *
 455 * Return: cb on success and NULL on failure
 456 */
 457struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
 458                                  enum mei_cb_file_ops type,
 459                                  const struct file *fp)
 460{
 461        struct mei_cl_cb *cb;
 462
 463        cb = mei_io_cb_init(cl, type, fp);
 464        if (!cb)
 465                return NULL;
 466
 467        if (mei_io_cb_alloc_buf(cb, length)) {
 468                mei_io_cb_free(cb);
 469                return NULL;
 470        }
 471
 472        return cb;
 473}
 474
 475/**
 476 * mei_cl_read_cb - find this cl's callback in the read list
 477 *     for a specific file
 478 *
 479 * @cl: host client
 480 * @fp: file pointer (matching cb file object), may be NULL
 481 *
 482 * Return: cb on success, NULL if cb is not found
 483 */
 484struct mei_cl_cb *mei_cl_read_cb(const struct mei_cl *cl, const struct file *fp)
 485{
 486        struct mei_cl_cb *cb;
 487
 488        list_for_each_entry(cb, &cl->rd_completed, list)
 489                if (!fp || fp == cb->fp)
 490                        return cb;
 491
 492        return NULL;
 493}
 494
 495/**
 496 * mei_cl_read_cb_flush - free client's read pending and completed cbs
 497 *   for a specific file
 498 *
 499 * @cl: host client
 500 * @fp: file pointer (matching cb file object), may be NULL
 501 */
 502void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp)
 503{
 504        struct mei_cl_cb *cb, *next;
 505
 506        list_for_each_entry_safe(cb, next, &cl->rd_completed, list)
 507                if (!fp || fp == cb->fp)
 508                        mei_io_cb_free(cb);
 509
 510
 511        list_for_each_entry_safe(cb, next, &cl->rd_pending, list)
 512                if (!fp || fp == cb->fp)
 513                        mei_io_cb_free(cb);
 514}
 515
 516/**
 517 * mei_cl_flush_queues - flushes queue lists belonging to cl.
 518 *
 519 * @cl: host client
 520 * @fp: file pointer (matching cb file object), may be NULL
 521 *
 522 * Return: 0 on success, -EINVAL if cl or cl->dev is NULL.
 523 */
 524int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp)
 525{
 526        struct mei_device *dev;
 527
 528        if (WARN_ON(!cl || !cl->dev))
 529                return -EINVAL;
 530
 531        dev = cl->dev;
 532
 533        cl_dbg(dev, cl, "remove list entry belonging to cl\n");
 534        mei_io_list_free(&cl->dev->write_list, cl);
 535        mei_io_list_free(&cl->dev->write_waiting_list, cl);
 536        mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
 537        mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
 538        mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
 539
 540        mei_cl_read_cb_flush(cl, fp);
 541
 542        return 0;
 543}
 544
 545
 546/**
 547 * mei_cl_init - initializes cl.
 548 *
 549 * @cl: host client to be initialized
 550 * @dev: mei device
 551 */
 552void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
 553{
 554        memset(cl, 0, sizeof(struct mei_cl));
 555        init_waitqueue_head(&cl->wait);
 556        init_waitqueue_head(&cl->rx_wait);
 557        init_waitqueue_head(&cl->tx_wait);
 558        init_waitqueue_head(&cl->ev_wait);
 559        INIT_LIST_HEAD(&cl->rd_completed);
 560        INIT_LIST_HEAD(&cl->rd_pending);
 561        INIT_LIST_HEAD(&cl->link);
 562        cl->writing_state = MEI_IDLE;
 563        cl->state = MEI_FILE_INITIALIZING;
 564        cl->dev = dev;
 565}
 566
 567/**
 568 * mei_cl_allocate - allocates cl  structure and sets it up.
 569 *
 570 * @dev: mei device
 571 * Return:  The allocated file or NULL on failure
 572 */
 573struct mei_cl *mei_cl_allocate(struct mei_device *dev)
 574{
 575        struct mei_cl *cl;
 576
 577        cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
 578        if (!cl)
 579                return NULL;
 580
 581        mei_cl_init(cl, dev);
 582
 583        return cl;
 584}
 585
 586/**
 587 * mei_cl_link - allocate host id in the host map
 588 *
 589 * @cl: host client
 590 *
 591 * Return: 0 on success
 592 *      -EINVAL on incorrect values
 593 *      -EMFILE if open count exceeded.
 594 */
 595int mei_cl_link(struct mei_cl *cl)
 596{
 597        struct mei_device *dev;
 598        long open_handle_count;
 599        int id;
 600
 601        if (WARN_ON(!cl || !cl->dev))
 602                return -EINVAL;
 603
 604        dev = cl->dev;
 605
 606        id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX);
 607        if (id >= MEI_CLIENTS_MAX) {
 608                dev_err(dev->dev, "id exceeded %d", MEI_CLIENTS_MAX);
 609                return -EMFILE;
 610        }
 611
 612        open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
 613        if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
 614                dev_err(dev->dev, "open_handle_count exceeded %d",
 615                        MEI_MAX_OPEN_HANDLE_COUNT);
 616                return -EMFILE;
 617        }
 618
 619        dev->open_handle_count++;
 620
 621        cl->host_client_id = id;
 622        list_add_tail(&cl->link, &dev->file_list);
 623
 624        set_bit(id, dev->host_clients_map);
 625
 626        cl->state = MEI_FILE_INITIALIZING;
 627
 628        cl_dbg(dev, cl, "link cl\n");
 629        return 0;
 630}
 631
 632/**
 633 * mei_cl_unlink - remove host client from the list
 634 *
 635 * @cl: host client
 636 *
 637 * Return: always 0
 638 */
 639int mei_cl_unlink(struct mei_cl *cl)
 640{
 641        struct mei_device *dev;
 642
 643        /* don't shout on error exit path */
 644        if (!cl)
 645                return 0;
 646
 647        /* amthif might not be initialized */
 648        if (!cl->dev)
 649                return 0;
 650
 651        dev = cl->dev;
 652
 653        cl_dbg(dev, cl, "unlink client");
 654
 655        if (dev->open_handle_count > 0)
 656                dev->open_handle_count--;
 657
 658        /* never clear the 0 bit */
 659        if (cl->host_client_id)
 660                clear_bit(cl->host_client_id, dev->host_clients_map);
 661
 662        list_del_init(&cl->link);
 663
 664        cl->state = MEI_FILE_INITIALIZING;
 665
 666        return 0;
 667}
 668
 669void mei_host_client_init(struct mei_device *dev)
 670{
 671        dev->dev_state = MEI_DEV_ENABLED;
 672        dev->reset_count = 0;
 673
 674        schedule_work(&dev->bus_rescan_work);
 675
 676        pm_runtime_mark_last_busy(dev->dev);
 677        dev_dbg(dev->dev, "rpm: autosuspend\n");
 678        pm_runtime_autosuspend(dev->dev);
 679}
 680
 681/**
 682 * mei_hbuf_acquire - try to acquire host buffer
 683 *
 684 * @dev: the device structure
 685 * Return: true if host buffer was acquired
 686 */
 687bool mei_hbuf_acquire(struct mei_device *dev)
 688{
 689        if (mei_pg_state(dev) == MEI_PG_ON ||
 690            mei_pg_in_transition(dev)) {
 691                dev_dbg(dev->dev, "device is in pg\n");
 692                return false;
 693        }
 694
 695        if (!dev->hbuf_is_ready) {
 696                dev_dbg(dev->dev, "hbuf is not ready\n");
 697                return false;
 698        }
 699
 700        dev->hbuf_is_ready = false;
 701
 702        return true;
 703}
 704
 705/**
 706 * mei_cl_wake_all - wake up readers, writers and event waiters so
 707 *                 they can be interrupted
 708 *
 709 * @cl: host client
 710 */
 711static void mei_cl_wake_all(struct mei_cl *cl)
 712{
 713        struct mei_device *dev = cl->dev;
 714
 715        /* synchronized under device mutex */
 716        if (waitqueue_active(&cl->rx_wait)) {
 717                cl_dbg(dev, cl, "Waking up reading client!\n");
 718                wake_up_interruptible(&cl->rx_wait);
 719        }
 720        /* synchronized under device mutex */
 721        if (waitqueue_active(&cl->tx_wait)) {
 722                cl_dbg(dev, cl, "Waking up writing client!\n");
 723                wake_up_interruptible(&cl->tx_wait);
 724        }
 725        /* synchronized under device mutex */
 726        if (waitqueue_active(&cl->ev_wait)) {
 727                cl_dbg(dev, cl, "Waking up waiting for event clients!\n");
 728                wake_up_interruptible(&cl->ev_wait);
 729        }
 730}
 731
 732/**
 733 * mei_cl_set_disconnected - set disconnected state and clear
 734 *   associated states and resources
 735 *
 736 * @cl: host client
 737 */
 738void mei_cl_set_disconnected(struct mei_cl *cl)
 739{
 740        struct mei_device *dev = cl->dev;
 741
 742        if (cl->state == MEI_FILE_DISCONNECTED ||
 743            cl->state == MEI_FILE_INITIALIZING)
 744                return;
 745
 746        cl->state = MEI_FILE_DISCONNECTED;
 747        mei_io_list_free(&dev->write_list, cl);
 748        mei_io_list_free(&dev->write_waiting_list, cl);
 749        mei_io_list_flush(&dev->ctrl_rd_list, cl);
 750        mei_io_list_flush(&dev->ctrl_wr_list, cl);
 751        mei_cl_wake_all(cl);
 752        cl->mei_flow_ctrl_creds = 0;
 753        cl->timer_count = 0;
 754
 755        if (!cl->me_cl)
 756                return;
 757
 758        if (!WARN_ON(cl->me_cl->connect_count == 0))
 759                cl->me_cl->connect_count--;
 760
 761        if (cl->me_cl->connect_count == 0)
 762                cl->me_cl->mei_flow_ctrl_creds = 0;
 763
 764        mei_me_cl_put(cl->me_cl);
 765        cl->me_cl = NULL;
 766}
 767
 768static int mei_cl_set_connecting(struct mei_cl *cl, struct mei_me_client *me_cl)
 769{
 770        if (!mei_me_cl_get(me_cl))
 771                return -ENOENT;
 772
 773        /* only one connection is allowed for fixed address clients */
 774        if (me_cl->props.fixed_address) {
 775                if (me_cl->connect_count) {
 776                        mei_me_cl_put(me_cl);
 777                        return -EBUSY;
 778                }
 779        }
 780
 781        cl->me_cl = me_cl;
 782        cl->state = MEI_FILE_CONNECTING;
 783        cl->me_cl->connect_count++;
 784
 785        return 0;
 786}
 787
 788/*
 789 * mei_cl_send_disconnect - send disconnect request
 790 *
 791 * @cl: host client
 792 * @cb: callback block
 793 *
 794 * Return: 0, OK; otherwise, error.
 795 */
 796static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb)
 797{
 798        struct mei_device *dev;
 799        int ret;
 800
 801        dev = cl->dev;
 802
 803        ret = mei_hbm_cl_disconnect_req(dev, cl);
 804        cl->status = ret;
 805        if (ret) {
 806                cl->state = MEI_FILE_DISCONNECT_REPLY;
 807                return ret;
 808        }
 809
 810        list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
 811        cl->timer_count = MEI_CONNECT_TIMEOUT;
 812
 813        return 0;
 814}
 815
 816/**
 817 * mei_cl_irq_disconnect - processes close related operation from
 818 *      interrupt thread context - send disconnect request
 819 *
 820 * @cl: client
 821 * @cb: callback block.
 822 * @cmpl_list: complete list.
 823 *
 824 * Return: 0, OK; otherwise, error.
 825 */
 826int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
 827                            struct mei_cl_cb *cmpl_list)
 828{
 829        struct mei_device *dev = cl->dev;
 830        u32 msg_slots;
 831        int slots;
 832        int ret;
 833
 834        msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
 835        slots = mei_hbuf_empty_slots(dev);
 836
 837        if (slots < msg_slots)
 838                return -EMSGSIZE;
 839
 840        ret = mei_cl_send_disconnect(cl, cb);
 841        if (ret)
 842                list_move_tail(&cb->list, &cmpl_list->list);
 843
 844        return ret;
 845}
 846
 847/**
 848 * __mei_cl_disconnect - disconnect host client from the me one
 849 *     internal function runtime pm has to be already acquired
 850 *
 851 * @cl: host client
 852 *
 853 * Return: 0 on success, <0 on failure.
 854 */
 855static int __mei_cl_disconnect(struct mei_cl *cl)
 856{
 857        struct mei_device *dev;
 858        struct mei_cl_cb *cb;
 859        int rets;
 860
 861        dev = cl->dev;
 862
 863        cl->state = MEI_FILE_DISCONNECTING;
 864
 865        cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT, NULL);
 866        rets = cb ? 0 : -ENOMEM;
 867        if (rets)
 868                goto out;
 869
 870        cl_dbg(dev, cl, "add disconnect cb to control write list\n");
 871        list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 872
 873        if (mei_hbuf_acquire(dev)) {
 874                rets = mei_cl_send_disconnect(cl, cb);
 875                if (rets) {
 876                        cl_err(dev, cl, "failed to disconnect.\n");
 877                        goto out;
 878                }
 879        }
 880
 881        mutex_unlock(&dev->device_lock);
 882        wait_event_timeout(cl->wait, cl->state == MEI_FILE_DISCONNECT_REPLY,
 883                           mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 884        mutex_lock(&dev->device_lock);
 885
 886        rets = cl->status;
 887        if (cl->state != MEI_FILE_DISCONNECT_REPLY) {
 888                cl_dbg(dev, cl, "timeout on disconnect from FW client.\n");
 889                rets = -ETIME;
 890        }
 891
 892out:
 893        /* we disconnect also on error */
 894        mei_cl_set_disconnected(cl);
 895        if (!rets)
 896                cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
 897
 898        mei_io_cb_free(cb);
 899        return rets;
 900}
 901
 902/**
 903 * mei_cl_disconnect - disconnect host client from the me one
 904 *
 905 * @cl: host client
 906 *
 907 * Locking: called under "dev->device_lock" lock
 908 *
 909 * Return: 0 on success, <0 on failure.
 910 */
 911int mei_cl_disconnect(struct mei_cl *cl)
 912{
 913        struct mei_device *dev;
 914        int rets;
 915
 916        if (WARN_ON(!cl || !cl->dev))
 917                return -ENODEV;
 918
 919        dev = cl->dev;
 920
 921        cl_dbg(dev, cl, "disconnecting");
 922
 923        if (!mei_cl_is_connected(cl))
 924                return 0;
 925
 926        if (mei_cl_is_fixed_address(cl)) {
 927                mei_cl_set_disconnected(cl);
 928                return 0;
 929        }
 930
 931        rets = pm_runtime_get(dev->dev);
 932        if (rets < 0 && rets != -EINPROGRESS) {
 933                pm_runtime_put_noidle(dev->dev);
 934                cl_err(dev, cl, "rpm: get failed %d\n", rets);
 935                return rets;
 936        }
 937
 938        rets = __mei_cl_disconnect(cl);
 939
 940        cl_dbg(dev, cl, "rpm: autosuspend\n");
 941        pm_runtime_mark_last_busy(dev->dev);
 942        pm_runtime_put_autosuspend(dev->dev);
 943
 944        return rets;
 945}
 946
 947
 948/**
 949 * mei_cl_is_other_connecting - checks if other
 950 *    client with the same me client id is connecting
 951 *
 952 * @cl: private data of the file object
 953 *
 954 * Return: true if other client is connected, false - otherwise.
 955 */
 956static bool mei_cl_is_other_connecting(struct mei_cl *cl)
 957{
 958        struct mei_device *dev;
 959        struct mei_cl_cb *cb;
 960
 961        dev = cl->dev;
 962
 963        list_for_each_entry(cb, &dev->ctrl_rd_list.list, list) {
 964                if (cb->fop_type == MEI_FOP_CONNECT &&
 965                    mei_cl_me_id(cl) == mei_cl_me_id(cb->cl))
 966                        return true;
 967        }
 968
 969        return false;
 970}
 971
 972/**
 973 * mei_cl_send_connect - send connect request
 974 *
 975 * @cl: host client
 976 * @cb: callback block
 977 *
 978 * Return: 0, OK; otherwise, error.
 979 */
 980static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb)
 981{
 982        struct mei_device *dev;
 983        int ret;
 984
 985        dev = cl->dev;
 986
 987        ret = mei_hbm_cl_connect_req(dev, cl);
 988        cl->status = ret;
 989        if (ret) {
 990                cl->state = MEI_FILE_DISCONNECT_REPLY;
 991                return ret;
 992        }
 993
 994        list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
 995        cl->timer_count = MEI_CONNECT_TIMEOUT;
 996        return 0;
 997}
 998
 999/**
1000 * mei_cl_irq_connect - send connect request in irq_thread context
1001 *
1002 * @cl: host client
1003 * @cb: callback block
1004 * @cmpl_list: complete list
1005 *
1006 * Return: 0, OK; otherwise, error.
1007 */
1008int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
1009                              struct mei_cl_cb *cmpl_list)
1010{
1011        struct mei_device *dev = cl->dev;
1012        u32 msg_slots;
1013        int slots;
1014        int rets;
1015
1016        msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
1017        slots = mei_hbuf_empty_slots(dev);
1018
1019        if (mei_cl_is_other_connecting(cl))
1020                return 0;
1021
1022        if (slots < msg_slots)
1023                return -EMSGSIZE;
1024
1025        rets = mei_cl_send_connect(cl, cb);
1026        if (rets)
1027                list_move_tail(&cb->list, &cmpl_list->list);
1028
1029        return rets;
1030}
1031
1032/**
1033 * mei_cl_connect - connect host client to the me one
1034 *
1035 * @cl: host client
1036 * @me_cl: me client
1037 * @file: pointer to file structure
1038 *
1039 * Locking: called under "dev->device_lock" lock
1040 *
1041 * Return: 0 on success, <0 on failure.
1042 */
1043int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
1044                  const struct file *file)
1045{
1046        struct mei_device *dev;
1047        struct mei_cl_cb *cb;
1048        int rets;
1049
1050        if (WARN_ON(!cl || !cl->dev || !me_cl))
1051                return -ENODEV;
1052
1053        dev = cl->dev;
1054
1055        rets = mei_cl_set_connecting(cl, me_cl);
1056        if (rets)
1057                return rets;
1058
1059        if (mei_cl_is_fixed_address(cl)) {
1060                cl->state = MEI_FILE_CONNECTED;
1061                return 0;
1062        }
1063
1064        rets = pm_runtime_get(dev->dev);
1065        if (rets < 0 && rets != -EINPROGRESS) {
1066                pm_runtime_put_noidle(dev->dev);
1067                cl_err(dev, cl, "rpm: get failed %d\n", rets);
1068                goto nortpm;
1069        }
1070
1071        cb = mei_io_cb_init(cl, MEI_FOP_CONNECT, file);
1072        rets = cb ? 0 : -ENOMEM;
1073        if (rets)
1074                goto out;
1075
1076        list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
1077
1078        /* run hbuf acquire last so we don't have to undo */
1079        if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
1080                rets = mei_cl_send_connect(cl, cb);
1081                if (rets)
1082                        goto out;
1083        }
1084
1085        mutex_unlock(&dev->device_lock);
1086        wait_event_timeout(cl->wait,
1087                        (cl->state == MEI_FILE_CONNECTED ||
1088                         cl->state == MEI_FILE_DISCONNECT_REQUIRED ||
1089                         cl->state == MEI_FILE_DISCONNECT_REPLY),
1090                        mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
1091        mutex_lock(&dev->device_lock);
1092
1093        if (!mei_cl_is_connected(cl)) {
1094                if (cl->state == MEI_FILE_DISCONNECT_REQUIRED) {
1095                        mei_io_list_flush(&dev->ctrl_rd_list, cl);
1096                        mei_io_list_flush(&dev->ctrl_wr_list, cl);
1097                         /* ignore disconnect return valuue;
1098                          * in case of failure reset will be invoked
1099                          */
1100                        __mei_cl_disconnect(cl);
1101                        rets = -EFAULT;
1102                        goto out;
1103                }
1104
1105                /* timeout or something went really wrong */
1106                if (!cl->status)
1107                        cl->status = -EFAULT;
1108        }
1109
1110        rets = cl->status;
1111out:
1112        cl_dbg(dev, cl, "rpm: autosuspend\n");
1113        pm_runtime_mark_last_busy(dev->dev);
1114        pm_runtime_put_autosuspend(dev->dev);
1115
1116        mei_io_cb_free(cb);
1117
1118nortpm:
1119        if (!mei_cl_is_connected(cl))
1120                mei_cl_set_disconnected(cl);
1121
1122        return rets;
1123}
1124
1125/**
1126 * mei_cl_alloc_linked - allocate and link host client
1127 *
1128 * @dev: the device structure
1129 *
1130 * Return: cl on success ERR_PTR on failure
1131 */
1132struct mei_cl *mei_cl_alloc_linked(struct mei_device *dev)
1133{
1134        struct mei_cl *cl;
1135        int ret;
1136
1137        cl = mei_cl_allocate(dev);
1138        if (!cl) {
1139                ret = -ENOMEM;
1140                goto err;
1141        }
1142
1143        ret = mei_cl_link(cl);
1144        if (ret)
1145                goto err;
1146
1147        return cl;
1148err:
1149        kfree(cl);
1150        return ERR_PTR(ret);
1151}
1152
1153
1154
1155/**
1156 * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
1157 *
1158 * @cl: host client
1159 * @fp: the file pointer associated with the pointer
1160 *
1161 * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
1162 */
1163static int mei_cl_flow_ctrl_creds(struct mei_cl *cl, const struct file *fp)
1164{
1165        int rets;
1166
1167        if (WARN_ON(!cl || !cl->me_cl))
1168                return -EINVAL;
1169
1170        if (cl->mei_flow_ctrl_creds > 0)
1171                return 1;
1172
1173        if (mei_cl_is_fixed_address(cl)) {
1174                rets = mei_cl_read_start(cl, mei_cl_mtu(cl), fp);
1175                if (rets && rets != -EBUSY)
1176                        return rets;
1177                return 1;
1178        }
1179
1180        if (mei_cl_is_single_recv_buf(cl)) {
1181                if (cl->me_cl->mei_flow_ctrl_creds > 0)
1182                        return 1;
1183        }
1184        return 0;
1185}
1186
1187/**
1188 * mei_cl_flow_ctrl_reduce - reduces flow_control.
1189 *
1190 * @cl: private data of the file object
1191 *
1192 * Return:
1193 *      0 on success
1194 *      -EINVAL when ctrl credits are <= 0
1195 */
1196static int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
1197{
1198        if (WARN_ON(!cl || !cl->me_cl))
1199                return -EINVAL;
1200
1201        if (mei_cl_is_fixed_address(cl))
1202                return 0;
1203
1204        if (mei_cl_is_single_recv_buf(cl)) {
1205                if (WARN_ON(cl->me_cl->mei_flow_ctrl_creds <= 0))
1206                        return -EINVAL;
1207                cl->me_cl->mei_flow_ctrl_creds--;
1208        } else {
1209                if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
1210                        return -EINVAL;
1211                cl->mei_flow_ctrl_creds--;
1212        }
1213        return 0;
1214}
1215
1216/**
1217 *  mei_cl_notify_fop2req - convert fop to proper request
1218 *
1219 * @fop: client notification start response command
1220 *
1221 * Return:  MEI_HBM_NOTIFICATION_START/STOP
1222 */
1223u8 mei_cl_notify_fop2req(enum mei_cb_file_ops fop)
1224{
1225        if (fop == MEI_FOP_NOTIFY_START)
1226                return MEI_HBM_NOTIFICATION_START;
1227        else
1228                return MEI_HBM_NOTIFICATION_STOP;
1229}
1230
1231/**
1232 *  mei_cl_notify_req2fop - convert notification request top file operation type
1233 *
1234 * @req: hbm notification request type
1235 *
1236 * Return:  MEI_FOP_NOTIFY_START/STOP
1237 */
1238enum mei_cb_file_ops mei_cl_notify_req2fop(u8 req)
1239{
1240        if (req == MEI_HBM_NOTIFICATION_START)
1241                return MEI_FOP_NOTIFY_START;
1242        else
1243                return MEI_FOP_NOTIFY_STOP;
1244}
1245
1246/**
1247 * mei_cl_irq_notify - send notification request in irq_thread context
1248 *
1249 * @cl: client
1250 * @cb: callback block.
1251 * @cmpl_list: complete list.
1252 *
1253 * Return: 0 on such and error otherwise.
1254 */
1255int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
1256                      struct mei_cl_cb *cmpl_list)
1257{
1258        struct mei_device *dev = cl->dev;
1259        u32 msg_slots;
1260        int slots;
1261        int ret;
1262        bool request;
1263
1264        msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
1265        slots = mei_hbuf_empty_slots(dev);
1266
1267        if (slots < msg_slots)
1268                return -EMSGSIZE;
1269
1270        request = mei_cl_notify_fop2req(cb->fop_type);
1271        ret = mei_hbm_cl_notify_req(dev, cl, request);
1272        if (ret) {
1273                cl->status = ret;
1274                list_move_tail(&cb->list, &cmpl_list->list);
1275                return ret;
1276        }
1277
1278        list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
1279        return 0;
1280}
1281
1282/**
1283 * mei_cl_notify_request - send notification stop/start request
1284 *
1285 * @cl: host client
1286 * @file: associate request with file
1287 * @request: 1 for start or 0 for stop
1288 *
1289 * Locking: called under "dev->device_lock" lock
1290 *
1291 * Return: 0 on such and error otherwise.
1292 */
1293int mei_cl_notify_request(struct mei_cl *cl,
1294                          const struct file *file, u8 request)
1295{
1296        struct mei_device *dev;
1297        struct mei_cl_cb *cb;
1298        enum mei_cb_file_ops fop_type;
1299        int rets;
1300
1301        if (WARN_ON(!cl || !cl->dev))
1302                return -ENODEV;
1303
1304        dev = cl->dev;
1305
1306        if (!dev->hbm_f_ev_supported) {
1307                cl_dbg(dev, cl, "notifications not supported\n");
1308                return -EOPNOTSUPP;
1309        }
1310
1311        rets = pm_runtime_get(dev->dev);
1312        if (rets < 0 && rets != -EINPROGRESS) {
1313                pm_runtime_put_noidle(dev->dev);
1314                cl_err(dev, cl, "rpm: get failed %d\n", rets);
1315                return rets;
1316        }
1317
1318        fop_type = mei_cl_notify_req2fop(request);
1319        cb = mei_io_cb_init(cl, fop_type, file);
1320        if (!cb) {
1321                rets = -ENOMEM;
1322                goto out;
1323        }
1324
1325        if (mei_hbuf_acquire(dev)) {
1326                if (mei_hbm_cl_notify_req(dev, cl, request)) {
1327                        rets = -ENODEV;
1328                        goto out;
1329                }
1330                list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
1331        } else {
1332                list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
1333        }
1334
1335        mutex_unlock(&dev->device_lock);
1336        wait_event_timeout(cl->wait, cl->notify_en == request,
1337                        mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
1338        mutex_lock(&dev->device_lock);
1339
1340        if (cl->notify_en != request) {
1341                mei_io_list_flush(&dev->ctrl_rd_list, cl);
1342                mei_io_list_flush(&dev->ctrl_wr_list, cl);
1343                if (!cl->status)
1344                        cl->status = -EFAULT;
1345        }
1346
1347        rets = cl->status;
1348
1349out:
1350        cl_dbg(dev, cl, "rpm: autosuspend\n");
1351        pm_runtime_mark_last_busy(dev->dev);
1352        pm_runtime_put_autosuspend(dev->dev);
1353
1354        mei_io_cb_free(cb);
1355        return rets;
1356}
1357
1358/**
1359 * mei_cl_notify - raise notification
1360 *
1361 * @cl: host client
1362 *
1363 * Locking: called under "dev->device_lock" lock
1364 */
1365void mei_cl_notify(struct mei_cl *cl)
1366{
1367        struct mei_device *dev;
1368
1369        if (!cl || !cl->dev)
1370                return;
1371
1372        dev = cl->dev;
1373
1374        if (!cl->notify_en)
1375                return;
1376
1377        cl_dbg(dev, cl, "notify event");
1378        cl->notify_ev = true;
1379        if (!mei_cl_bus_notify_event(cl))
1380                wake_up_interruptible(&cl->ev_wait);
1381
1382        if (cl->ev_async)
1383                kill_fasync(&cl->ev_async, SIGIO, POLL_PRI);
1384
1385}
1386
1387/**
1388 * mei_cl_notify_get - get or wait for notification event
1389 *
1390 * @cl: host client
1391 * @block: this request is blocking
1392 * @notify_ev: true if notification event was received
1393 *
1394 * Locking: called under "dev->device_lock" lock
1395 *
1396 * Return: 0 on such and error otherwise.
1397 */
1398int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev)
1399{
1400        struct mei_device *dev;
1401        int rets;
1402
1403        *notify_ev = false;
1404
1405        if (WARN_ON(!cl || !cl->dev))
1406                return -ENODEV;
1407
1408        dev = cl->dev;
1409
1410        if (!mei_cl_is_connected(cl))
1411                return -ENODEV;
1412
1413        if (cl->notify_ev)
1414                goto out;
1415
1416        if (!block)
1417                return -EAGAIN;
1418
1419        mutex_unlock(&dev->device_lock);
1420        rets = wait_event_interruptible(cl->ev_wait, cl->notify_ev);
1421        mutex_lock(&dev->device_lock);
1422
1423        if (rets < 0)
1424                return rets;
1425
1426out:
1427        *notify_ev = cl->notify_ev;
1428        cl->notify_ev = false;
1429        return 0;
1430}
1431
1432/**
1433 * mei_cl_is_read_fc_cb - check if read cb is waiting for flow control
1434 *                        for given host client
1435 *
1436 * @cl: host client
1437 *
1438 * Return: true, if found at least one cb.
1439 */
1440static bool mei_cl_is_read_fc_cb(struct mei_cl *cl)
1441{
1442        struct mei_device *dev = cl->dev;
1443        struct mei_cl_cb *cb;
1444
1445        list_for_each_entry(cb, &dev->ctrl_wr_list.list, list)
1446                if (cb->fop_type == MEI_FOP_READ && cb->cl == cl)
1447                        return true;
1448        return false;
1449}
1450
1451/**
1452 * mei_cl_read_start - the start read client message function.
1453 *
1454 * @cl: host client
1455 * @length: number of bytes to read
1456 * @fp: pointer to file structure
1457 *
1458 * Return: 0 on success, <0 on failure.
1459 */
1460int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp)
1461{
1462        struct mei_device *dev;
1463        struct mei_cl_cb *cb;
1464        int rets;
1465
1466        if (WARN_ON(!cl || !cl->dev))
1467                return -ENODEV;
1468
1469        dev = cl->dev;
1470
1471        if (!mei_cl_is_connected(cl))
1472                return -ENODEV;
1473
1474        /* HW currently supports only one pending read */
1475        if (!list_empty(&cl->rd_pending) || mei_cl_is_read_fc_cb(cl))
1476                return -EBUSY;
1477
1478        if (!mei_me_cl_is_active(cl->me_cl)) {
1479                cl_err(dev, cl, "no such me client\n");
1480                return  -ENOTTY;
1481        }
1482
1483        /* always allocate at least client max message */
1484        length = max_t(size_t, length, mei_cl_mtu(cl));
1485        cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp);
1486        if (!cb)
1487                return -ENOMEM;
1488
1489        if (mei_cl_is_fixed_address(cl)) {
1490                list_add_tail(&cb->list, &cl->rd_pending);
1491                return 0;
1492        }
1493
1494        rets = pm_runtime_get(dev->dev);
1495        if (rets < 0 && rets != -EINPROGRESS) {
1496                pm_runtime_put_noidle(dev->dev);
1497                cl_err(dev, cl, "rpm: get failed %d\n", rets);
1498                goto nortpm;
1499        }
1500
1501        if (mei_hbuf_acquire(dev)) {
1502                rets = mei_hbm_cl_flow_control_req(dev, cl);
1503                if (rets < 0)
1504                        goto out;
1505
1506                list_add_tail(&cb->list, &cl->rd_pending);
1507        } else {
1508                rets = 0;
1509                list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
1510        }
1511
1512out:
1513        cl_dbg(dev, cl, "rpm: autosuspend\n");
1514        pm_runtime_mark_last_busy(dev->dev);
1515        pm_runtime_put_autosuspend(dev->dev);
1516nortpm:
1517        if (rets)
1518                mei_io_cb_free(cb);
1519
1520        return rets;
1521}
1522
1523/**
1524 * mei_cl_irq_write - write a message to device
1525 *      from the interrupt thread context
1526 *
1527 * @cl: client
1528 * @cb: callback block.
1529 * @cmpl_list: complete list.
1530 *
1531 * Return: 0, OK; otherwise error.
1532 */
1533int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
1534                     struct mei_cl_cb *cmpl_list)
1535{
1536        struct mei_device *dev;
1537        struct mei_msg_data *buf;
1538        struct mei_msg_hdr mei_hdr;
1539        size_t len;
1540        u32 msg_slots;
1541        int slots;
1542        int rets;
1543        bool first_chunk;
1544
1545        if (WARN_ON(!cl || !cl->dev))
1546                return -ENODEV;
1547
1548        dev = cl->dev;
1549
1550        buf = &cb->buf;
1551
1552        first_chunk = cb->buf_idx == 0;
1553
1554        rets = first_chunk ? mei_cl_flow_ctrl_creds(cl, cb->fp) : 1;
1555        if (rets < 0)
1556                return rets;
1557
1558        if (rets == 0) {
1559                cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
1560                return 0;
1561        }
1562
1563        slots = mei_hbuf_empty_slots(dev);
1564        len = buf->size - cb->buf_idx;
1565        msg_slots = mei_data2slots(len);
1566
1567        mei_hdr.host_addr = mei_cl_host_addr(cl);
1568        mei_hdr.me_addr = mei_cl_me_id(cl);
1569        mei_hdr.reserved = 0;
1570        mei_hdr.internal = cb->internal;
1571
1572        if (slots >= msg_slots) {
1573                mei_hdr.length = len;
1574                mei_hdr.msg_complete = 1;
1575        /* Split the message only if we can write the whole host buffer */
1576        } else if (slots == dev->hbuf_depth) {
1577                msg_slots = slots;
1578                len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
1579                mei_hdr.length = len;
1580                mei_hdr.msg_complete = 0;
1581        } else {
1582                /* wait for next time the host buffer is empty */
1583                return 0;
1584        }
1585
1586        cl_dbg(dev, cl, "buf: size = %zu idx = %zu\n",
1587                        cb->buf.size, cb->buf_idx);
1588
1589        rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
1590        if (rets) {
1591                cl->status = rets;
1592                list_move_tail(&cb->list, &cmpl_list->list);
1593                return rets;
1594        }
1595
1596        cl->status = 0;
1597        cl->writing_state = MEI_WRITING;
1598        cb->buf_idx += mei_hdr.length;
1599        cb->completed = mei_hdr.msg_complete == 1;
1600
1601        if (first_chunk) {
1602                if (mei_cl_flow_ctrl_reduce(cl))
1603                        return -EIO;
1604        }
1605
1606        if (mei_hdr.msg_complete)
1607                list_move_tail(&cb->list, &dev->write_waiting_list.list);
1608
1609        return 0;
1610}
1611
1612/**
1613 * mei_cl_write - submit a write cb to mei device
1614 *      assumes device_lock is locked
1615 *
1616 * @cl: host client
1617 * @cb: write callback with filled data
1618 * @blocking: block until completed
1619 *
1620 * Return: number of bytes sent on success, <0 on failure.
1621 */
1622int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
1623{
1624        struct mei_device *dev;
1625        struct mei_msg_data *buf;
1626        struct mei_msg_hdr mei_hdr;
1627        int size;
1628        int rets;
1629
1630
1631        if (WARN_ON(!cl || !cl->dev))
1632                return -ENODEV;
1633
1634        if (WARN_ON(!cb))
1635                return -EINVAL;
1636
1637        dev = cl->dev;
1638
1639        buf = &cb->buf;
1640        size = buf->size;
1641
1642        cl_dbg(dev, cl, "size=%d\n", size);
1643
1644        rets = pm_runtime_get(dev->dev);
1645        if (rets < 0 && rets != -EINPROGRESS) {
1646                pm_runtime_put_noidle(dev->dev);
1647                cl_err(dev, cl, "rpm: get failed %d\n", rets);
1648                goto free;
1649        }
1650
1651        cb->buf_idx = 0;
1652        cl->writing_state = MEI_IDLE;
1653
1654        mei_hdr.host_addr = mei_cl_host_addr(cl);
1655        mei_hdr.me_addr = mei_cl_me_id(cl);
1656        mei_hdr.reserved = 0;
1657        mei_hdr.msg_complete = 0;
1658        mei_hdr.internal = cb->internal;
1659
1660        rets = mei_cl_flow_ctrl_creds(cl, cb->fp);
1661        if (rets < 0)
1662                goto err;
1663
1664        if (rets == 0) {
1665                cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
1666                rets = size;
1667                goto out;
1668        }
1669        if (!mei_hbuf_acquire(dev)) {
1670                cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n");
1671                rets = size;
1672                goto out;
1673        }
1674
1675        /* Check for a maximum length */
1676        if (size > mei_hbuf_max_len(dev)) {
1677                mei_hdr.length = mei_hbuf_max_len(dev);
1678                mei_hdr.msg_complete = 0;
1679        } else {
1680                mei_hdr.length = size;
1681                mei_hdr.msg_complete = 1;
1682        }
1683
1684        rets = mei_write_message(dev, &mei_hdr, buf->data);
1685        if (rets)
1686                goto err;
1687
1688        rets = mei_cl_flow_ctrl_reduce(cl);
1689        if (rets)
1690                goto err;
1691
1692        cl->writing_state = MEI_WRITING;
1693        cb->buf_idx = mei_hdr.length;
1694        cb->completed = mei_hdr.msg_complete == 1;
1695
1696out:
1697        if (mei_hdr.msg_complete)
1698                list_add_tail(&cb->list, &dev->write_waiting_list.list);
1699        else
1700                list_add_tail(&cb->list, &dev->write_list.list);
1701
1702        cb = NULL;
1703        if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
1704
1705                mutex_unlock(&dev->device_lock);
1706                rets = wait_event_interruptible(cl->tx_wait,
1707                                cl->writing_state == MEI_WRITE_COMPLETE ||
1708                                (!mei_cl_is_connected(cl)));
1709                mutex_lock(&dev->device_lock);
1710                /* wait_event_interruptible returns -ERESTARTSYS */
1711                if (rets) {
1712                        if (signal_pending(current))
1713                                rets = -EINTR;
1714                        goto err;
1715                }
1716                if (cl->writing_state != MEI_WRITE_COMPLETE) {
1717                        rets = -EFAULT;
1718                        goto err;
1719                }
1720        }
1721
1722        rets = size;
1723err:
1724        cl_dbg(dev, cl, "rpm: autosuspend\n");
1725        pm_runtime_mark_last_busy(dev->dev);
1726        pm_runtime_put_autosuspend(dev->dev);
1727free:
1728        mei_io_cb_free(cb);
1729
1730        return rets;
1731}
1732
1733
1734/**
1735 * mei_cl_complete - processes completed operation for a client
1736 *
1737 * @cl: private data of the file object.
1738 * @cb: callback block.
1739 */
1740void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
1741{
1742        struct mei_device *dev = cl->dev;
1743
1744        switch (cb->fop_type) {
1745        case MEI_FOP_WRITE:
1746                mei_io_cb_free(cb);
1747                cl->writing_state = MEI_WRITE_COMPLETE;
1748                if (waitqueue_active(&cl->tx_wait)) {
1749                        wake_up_interruptible(&cl->tx_wait);
1750                } else {
1751                        pm_runtime_mark_last_busy(dev->dev);
1752                        pm_request_autosuspend(dev->dev);
1753                }
1754                break;
1755
1756        case MEI_FOP_READ:
1757                list_add_tail(&cb->list, &cl->rd_completed);
1758                if (!mei_cl_bus_rx_event(cl))
1759                        wake_up_interruptible(&cl->rx_wait);
1760                break;
1761
1762        case MEI_FOP_CONNECT:
1763        case MEI_FOP_DISCONNECT:
1764        case MEI_FOP_NOTIFY_STOP:
1765        case MEI_FOP_NOTIFY_START:
1766                if (waitqueue_active(&cl->wait))
1767                        wake_up(&cl->wait);
1768
1769                break;
1770        default:
1771                BUG_ON(0);
1772        }
1773}
1774
1775
1776/**
1777 * mei_cl_all_disconnect - disconnect forcefully all connected clients
1778 *
1779 * @dev: mei device
1780 */
1781void mei_cl_all_disconnect(struct mei_device *dev)
1782{
1783        struct mei_cl *cl;
1784
1785        list_for_each_entry(cl, &dev->file_list, link)
1786                mei_cl_set_disconnected(cl);
1787}
1788