Lines Matching refs:cl
319 cb->cl->tx_cb_queued++; in mei_tx_cb_enqueue()
331 if (!WARN_ON(cb->cl->tx_cb_queued == 0)) in mei_tx_cb_dequeue()
332 cb->cl->tx_cb_queued--; in mei_tx_cb_dequeue()
345 static void mei_cl_set_read_by_fp(const struct mei_cl *cl, in mei_cl_set_read_by_fp() argument
350 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_set_read_by_fp()
367 static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, in mei_io_cb_init() argument
379 cb->cl = cl; in mei_io_cb_init()
395 const struct mei_cl *cl) in mei_io_list_flush_cl() argument
400 if (cl == cb->cl) { in mei_io_list_flush_cl()
416 const struct mei_cl *cl, in mei_io_tx_list_free_cl() argument
422 if (cl == cb->cl && (!fp || fp == cb->fp)) in mei_io_tx_list_free_cl()
447 static void mei_cl_free_pending(struct mei_cl *cl) in mei_cl_free_pending() argument
451 cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); in mei_cl_free_pending()
465 struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, in mei_cl_alloc_cb() argument
471 cb = mei_io_cb_init(cl, fop_type, fp); in mei_cl_alloc_cb()
500 struct mei_cl_cb *mei_cl_enqueue_ctrl_wr_cb(struct mei_cl *cl, size_t length, in mei_cl_enqueue_ctrl_wr_cb() argument
508 length = max_t(size_t, length, mei_cl_mtu(cl)); in mei_cl_enqueue_ctrl_wr_cb()
510 cb = mei_cl_alloc_cb(cl, length, fop_type, fp); in mei_cl_enqueue_ctrl_wr_cb()
514 list_add_tail(&cb->list, &cl->dev->ctrl_wr_list); in mei_cl_enqueue_ctrl_wr_cb()
527 struct mei_cl_cb *mei_cl_read_cb(struct mei_cl *cl, const struct file *fp) in mei_cl_read_cb() argument
532 spin_lock(&cl->rd_completed_lock); in mei_cl_read_cb()
533 list_for_each_entry(cb, &cl->rd_completed, list) in mei_cl_read_cb()
538 spin_unlock(&cl->rd_completed_lock); in mei_cl_read_cb()
550 int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp) in mei_cl_flush_queues() argument
554 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flush_queues()
557 dev = cl->dev; in mei_cl_flush_queues()
559 cl_dbg(dev, cl, "remove list entry belonging to cl\n"); in mei_cl_flush_queues()
560 mei_io_tx_list_free_cl(&cl->dev->write_list, cl, fp); in mei_cl_flush_queues()
561 mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl, fp); in mei_cl_flush_queues()
564 mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl); in mei_cl_flush_queues()
565 mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl); in mei_cl_flush_queues()
566 mei_cl_free_pending(cl); in mei_cl_flush_queues()
568 spin_lock(&cl->rd_completed_lock); in mei_cl_flush_queues()
569 mei_io_list_free_fp(&cl->rd_completed, fp); in mei_cl_flush_queues()
570 spin_unlock(&cl->rd_completed_lock); in mei_cl_flush_queues()
581 static void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) in mei_cl_init() argument
583 memset(cl, 0, sizeof(*cl)); in mei_cl_init()
584 init_waitqueue_head(&cl->wait); in mei_cl_init()
585 init_waitqueue_head(&cl->rx_wait); in mei_cl_init()
586 init_waitqueue_head(&cl->tx_wait); in mei_cl_init()
587 init_waitqueue_head(&cl->ev_wait); in mei_cl_init()
588 INIT_LIST_HEAD(&cl->vtag_map); in mei_cl_init()
589 spin_lock_init(&cl->rd_completed_lock); in mei_cl_init()
590 INIT_LIST_HEAD(&cl->rd_completed); in mei_cl_init()
591 INIT_LIST_HEAD(&cl->rd_pending); in mei_cl_init()
592 INIT_LIST_HEAD(&cl->link); in mei_cl_init()
593 cl->writing_state = MEI_IDLE; in mei_cl_init()
594 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_init()
595 cl->dev = dev; in mei_cl_init()
606 struct mei_cl *cl; in mei_cl_allocate() local
608 cl = kmalloc(sizeof(*cl), GFP_KERNEL); in mei_cl_allocate()
609 if (!cl) in mei_cl_allocate()
612 mei_cl_init(cl, dev); in mei_cl_allocate()
614 return cl; in mei_cl_allocate()
626 int mei_cl_link(struct mei_cl *cl) in mei_cl_link() argument
631 if (WARN_ON(!cl || !cl->dev)) in mei_cl_link()
634 dev = cl->dev; in mei_cl_link()
650 cl->host_client_id = id; in mei_cl_link()
651 list_add_tail(&cl->link, &dev->file_list); in mei_cl_link()
655 cl->state = MEI_FILE_INITIALIZING; in mei_cl_link()
657 cl_dbg(dev, cl, "link cl\n"); in mei_cl_link()
668 int mei_cl_unlink(struct mei_cl *cl) in mei_cl_unlink() argument
673 if (!cl) in mei_cl_unlink()
676 if (WARN_ON(!cl->dev)) in mei_cl_unlink()
679 dev = cl->dev; in mei_cl_unlink()
681 cl_dbg(dev, cl, "unlink client"); in mei_cl_unlink()
683 if (cl->state == MEI_FILE_UNINITIALIZED) in mei_cl_unlink()
690 if (cl->host_client_id) in mei_cl_unlink()
691 clear_bit(cl->host_client_id, dev->host_clients_map); in mei_cl_unlink()
693 list_del_init(&cl->link); in mei_cl_unlink()
695 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_unlink()
696 cl->writing_state = MEI_IDLE; in mei_cl_unlink()
698 WARN_ON(!list_empty(&cl->rd_completed) || in mei_cl_unlink()
699 !list_empty(&cl->rd_pending) || in mei_cl_unlink()
700 !list_empty(&cl->link)); in mei_cl_unlink()
747 static void mei_cl_wake_all(struct mei_cl *cl) in mei_cl_wake_all() argument
749 struct mei_device *dev = cl->dev; in mei_cl_wake_all()
752 if (waitqueue_active(&cl->rx_wait)) { in mei_cl_wake_all()
753 cl_dbg(dev, cl, "Waking up reading client!\n"); in mei_cl_wake_all()
754 wake_up_interruptible(&cl->rx_wait); in mei_cl_wake_all()
757 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_wake_all()
758 cl_dbg(dev, cl, "Waking up writing client!\n"); in mei_cl_wake_all()
759 wake_up_interruptible(&cl->tx_wait); in mei_cl_wake_all()
762 if (waitqueue_active(&cl->ev_wait)) { in mei_cl_wake_all()
763 cl_dbg(dev, cl, "Waking up waiting for event clients!\n"); in mei_cl_wake_all()
764 wake_up_interruptible(&cl->ev_wait); in mei_cl_wake_all()
767 if (waitqueue_active(&cl->wait)) { in mei_cl_wake_all()
768 cl_dbg(dev, cl, "Waking up ctrl write clients!\n"); in mei_cl_wake_all()
769 wake_up(&cl->wait); in mei_cl_wake_all()
779 static void mei_cl_set_disconnected(struct mei_cl *cl) in mei_cl_set_disconnected() argument
781 struct mei_device *dev = cl->dev; in mei_cl_set_disconnected()
783 if (cl->state == MEI_FILE_DISCONNECTED || in mei_cl_set_disconnected()
784 cl->state <= MEI_FILE_INITIALIZING) in mei_cl_set_disconnected()
787 cl->state = MEI_FILE_DISCONNECTED; in mei_cl_set_disconnected()
788 mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); in mei_cl_set_disconnected()
789 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); in mei_cl_set_disconnected()
790 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_set_disconnected()
791 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_set_disconnected()
792 mei_cl_wake_all(cl); in mei_cl_set_disconnected()
793 cl->rx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
794 cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
795 cl->timer_count = 0; in mei_cl_set_disconnected()
797 if (!cl->me_cl) in mei_cl_set_disconnected()
800 if (!WARN_ON(cl->me_cl->connect_count == 0)) in mei_cl_set_disconnected()
801 cl->me_cl->connect_count--; in mei_cl_set_disconnected()
803 if (cl->me_cl->connect_count == 0) in mei_cl_set_disconnected()
804 cl->me_cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
806 mei_me_cl_put(cl->me_cl); in mei_cl_set_disconnected()
807 cl->me_cl = NULL; in mei_cl_set_disconnected()
810 static int mei_cl_set_connecting(struct mei_cl *cl, struct mei_me_client *me_cl) in mei_cl_set_connecting() argument
823 cl->me_cl = me_cl; in mei_cl_set_connecting()
824 cl->state = MEI_FILE_CONNECTING; in mei_cl_set_connecting()
825 cl->me_cl->connect_count++; in mei_cl_set_connecting()
838 static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_send_disconnect() argument
843 dev = cl->dev; in mei_cl_send_disconnect()
845 ret = mei_hbm_cl_disconnect_req(dev, cl); in mei_cl_send_disconnect()
846 cl->status = ret; in mei_cl_send_disconnect()
848 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_disconnect()
853 cl->timer_count = dev->timeouts.connect; in mei_cl_send_disconnect()
869 int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_disconnect() argument
872 struct mei_device *dev = cl->dev; in mei_cl_irq_disconnect()
885 ret = mei_cl_send_disconnect(cl, cb); in mei_cl_irq_disconnect()
900 static int __mei_cl_disconnect(struct mei_cl *cl) in __mei_cl_disconnect() argument
906 dev = cl->dev; in __mei_cl_disconnect()
908 cl->state = MEI_FILE_DISCONNECTING; in __mei_cl_disconnect()
910 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT, NULL); in __mei_cl_disconnect()
917 rets = mei_cl_send_disconnect(cl, cb); in __mei_cl_disconnect()
919 cl_err(dev, cl, "failed to disconnect.\n"); in __mei_cl_disconnect()
925 wait_event_timeout(cl->wait, in __mei_cl_disconnect()
926 cl->state == MEI_FILE_DISCONNECT_REPLY || in __mei_cl_disconnect()
927 cl->state == MEI_FILE_DISCONNECTED, in __mei_cl_disconnect()
931 rets = cl->status; in __mei_cl_disconnect()
932 if (cl->state != MEI_FILE_DISCONNECT_REPLY && in __mei_cl_disconnect()
933 cl->state != MEI_FILE_DISCONNECTED) { in __mei_cl_disconnect()
934 cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); in __mei_cl_disconnect()
940 mei_cl_set_disconnected(cl); in __mei_cl_disconnect()
942 cl_dbg(dev, cl, "successfully disconnected from FW client.\n"); in __mei_cl_disconnect()
957 int mei_cl_disconnect(struct mei_cl *cl) in mei_cl_disconnect() argument
962 if (WARN_ON(!cl || !cl->dev)) in mei_cl_disconnect()
965 dev = cl->dev; in mei_cl_disconnect()
967 cl_dbg(dev, cl, "disconnecting"); in mei_cl_disconnect()
969 if (!mei_cl_is_connected(cl)) in mei_cl_disconnect()
972 if (mei_cl_is_fixed_address(cl)) { in mei_cl_disconnect()
973 mei_cl_set_disconnected(cl); in mei_cl_disconnect()
979 cl_dbg(dev, cl, "Device is powering down, don't bother with disconnection\n"); in mei_cl_disconnect()
980 mei_cl_set_disconnected(cl); in mei_cl_disconnect()
987 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_disconnect()
991 rets = __mei_cl_disconnect(cl); in mei_cl_disconnect()
993 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_disconnect()
1009 static bool mei_cl_is_other_connecting(struct mei_cl *cl) in mei_cl_is_other_connecting() argument
1014 dev = cl->dev; in mei_cl_is_other_connecting()
1018 mei_cl_me_id(cl) == mei_cl_me_id(cb->cl)) in mei_cl_is_other_connecting()
1033 static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_send_connect() argument
1038 dev = cl->dev; in mei_cl_send_connect()
1040 ret = mei_hbm_cl_connect_req(dev, cl); in mei_cl_send_connect()
1041 cl->status = ret; in mei_cl_send_connect()
1043 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_connect()
1048 cl->timer_count = dev->timeouts.connect; in mei_cl_send_connect()
1062 int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_connect() argument
1065 struct mei_device *dev = cl->dev; in mei_cl_irq_connect()
1070 if (mei_cl_is_other_connecting(cl)) in mei_cl_irq_connect()
1081 rets = mei_cl_send_connect(cl, cb); in mei_cl_irq_connect()
1099 int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, in mei_cl_connect() argument
1106 if (WARN_ON(!cl || !cl->dev || !me_cl)) in mei_cl_connect()
1109 dev = cl->dev; in mei_cl_connect()
1111 rets = mei_cl_set_connecting(cl, me_cl); in mei_cl_connect()
1115 if (mei_cl_is_fixed_address(cl)) { in mei_cl_connect()
1116 cl->state = MEI_FILE_CONNECTED; in mei_cl_connect()
1124 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_connect()
1128 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_CONNECT, fp); in mei_cl_connect()
1135 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { in mei_cl_connect()
1136 rets = mei_cl_send_connect(cl, cb); in mei_cl_connect()
1142 wait_event_timeout(cl->wait, in mei_cl_connect()
1143 (cl->state == MEI_FILE_CONNECTED || in mei_cl_connect()
1144 cl->state == MEI_FILE_DISCONNECTED || in mei_cl_connect()
1145 cl->state == MEI_FILE_DISCONNECT_REQUIRED || in mei_cl_connect()
1146 cl->state == MEI_FILE_DISCONNECT_REPLY), in mei_cl_connect()
1150 if (!mei_cl_is_connected(cl)) { in mei_cl_connect()
1151 if (cl->state == MEI_FILE_DISCONNECT_REQUIRED) { in mei_cl_connect()
1152 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_connect()
1153 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_connect()
1157 __mei_cl_disconnect(cl); in mei_cl_connect()
1163 if (!cl->status) in mei_cl_connect()
1164 cl->status = -EFAULT; in mei_cl_connect()
1167 rets = cl->status; in mei_cl_connect()
1169 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_connect()
1176 if (!mei_cl_is_connected(cl)) in mei_cl_connect()
1177 mei_cl_set_disconnected(cl); in mei_cl_connect()
1191 struct mei_cl *cl; in mei_cl_alloc_linked() local
1194 cl = mei_cl_allocate(dev); in mei_cl_alloc_linked()
1195 if (!cl) { in mei_cl_alloc_linked()
1200 ret = mei_cl_link(cl); in mei_cl_alloc_linked()
1204 return cl; in mei_cl_alloc_linked()
1206 kfree(cl); in mei_cl_alloc_linked()
1217 static int mei_cl_tx_flow_ctrl_creds(struct mei_cl *cl) in mei_cl_tx_flow_ctrl_creds() argument
1219 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds()
1222 if (cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1225 if (mei_cl_is_fixed_address(cl)) in mei_cl_tx_flow_ctrl_creds()
1228 if (mei_cl_is_single_recv_buf(cl)) { in mei_cl_tx_flow_ctrl_creds()
1229 if (cl->me_cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1245 static int mei_cl_tx_flow_ctrl_creds_reduce(struct mei_cl *cl) in mei_cl_tx_flow_ctrl_creds_reduce() argument
1247 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds_reduce()
1250 if (mei_cl_is_fixed_address(cl)) in mei_cl_tx_flow_ctrl_creds_reduce()
1253 if (mei_cl_is_single_recv_buf(cl)) { in mei_cl_tx_flow_ctrl_creds_reduce()
1254 if (WARN_ON(cl->me_cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1256 cl->me_cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1258 if (WARN_ON(cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1260 cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1300 const struct file *mei_cl_fp_by_vtag(const struct mei_cl *cl, u8 vtag) in mei_cl_fp_by_vtag() argument
1304 list_for_each_entry(vtag_l, &cl->vtag_map, list) in mei_cl_fp_by_vtag()
1306 if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || in mei_cl_fp_by_vtag()
1319 static void mei_cl_reset_read_by_vtag(const struct mei_cl *cl, u8 vtag) in mei_cl_reset_read_by_vtag() argument
1323 list_for_each_entry(vtag_l, &cl->vtag_map, list) { in mei_cl_reset_read_by_vtag()
1325 if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || in mei_cl_reset_read_by_vtag()
1339 static void mei_cl_read_vtag_add_fc(struct mei_cl *cl) in mei_cl_read_vtag_add_fc() argument
1343 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_read_vtag_add_fc()
1345 if (mei_cl_enqueue_ctrl_wr_cb(cl, in mei_cl_read_vtag_add_fc()
1346 mei_cl_mtu(cl), in mei_cl_read_vtag_add_fc()
1349 cl->rx_flow_ctrl_creds++; in mei_cl_read_vtag_add_fc()
1364 int mei_cl_vt_support_check(const struct mei_cl *cl) in mei_cl_vt_support_check() argument
1366 struct mei_device *dev = cl->dev; in mei_cl_vt_support_check()
1371 if (!cl->me_cl) in mei_cl_vt_support_check()
1374 return cl->me_cl->props.vt_supported ? 0 : -EOPNOTSUPP; in mei_cl_vt_support_check()
1385 void mei_cl_add_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_add_rd_completed() argument
1389 if (!mei_cl_vt_support_check(cl)) { in mei_cl_add_rd_completed()
1390 fp = mei_cl_fp_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1397 mei_cl_reset_read_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1398 mei_cl_read_vtag_add_fc(cl); in mei_cl_add_rd_completed()
1401 spin_lock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1402 list_add_tail(&cb->list, &cl->rd_completed); in mei_cl_add_rd_completed()
1403 spin_unlock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1413 void mei_cl_del_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_del_rd_completed() argument
1415 spin_lock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1417 spin_unlock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1459 int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_notify() argument
1462 struct mei_device *dev = cl->dev; in mei_cl_irq_notify()
1477 ret = mei_hbm_cl_notify_req(dev, cl, request); in mei_cl_irq_notify()
1479 cl->status = ret; in mei_cl_irq_notify()
1499 int mei_cl_notify_request(struct mei_cl *cl, in mei_cl_notify_request() argument
1507 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_request()
1510 dev = cl->dev; in mei_cl_notify_request()
1513 cl_dbg(dev, cl, "notifications not supported\n"); in mei_cl_notify_request()
1517 if (!mei_cl_is_connected(cl)) in mei_cl_notify_request()
1523 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_notify_request()
1528 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, fop_type, fp); in mei_cl_notify_request()
1535 if (mei_hbm_cl_notify_req(dev, cl, request)) { in mei_cl_notify_request()
1543 wait_event_timeout(cl->wait, in mei_cl_notify_request()
1544 cl->notify_en == request || in mei_cl_notify_request()
1545 cl->status || in mei_cl_notify_request()
1546 !mei_cl_is_connected(cl), in mei_cl_notify_request()
1550 if (cl->notify_en != request && !cl->status) in mei_cl_notify_request()
1551 cl->status = -EFAULT; in mei_cl_notify_request()
1553 rets = cl->status; in mei_cl_notify_request()
1556 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_notify_request()
1571 void mei_cl_notify(struct mei_cl *cl) in mei_cl_notify() argument
1575 if (!cl || !cl->dev) in mei_cl_notify()
1578 dev = cl->dev; in mei_cl_notify()
1580 if (!cl->notify_en) in mei_cl_notify()
1583 cl_dbg(dev, cl, "notify event"); in mei_cl_notify()
1584 cl->notify_ev = true; in mei_cl_notify()
1585 if (!mei_cl_bus_notify_event(cl)) in mei_cl_notify()
1586 wake_up_interruptible(&cl->ev_wait); in mei_cl_notify()
1588 if (cl->ev_async) in mei_cl_notify()
1589 kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); in mei_cl_notify()
1604 int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev) in mei_cl_notify_get() argument
1611 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_get()
1614 dev = cl->dev; in mei_cl_notify_get()
1617 cl_dbg(dev, cl, "notifications not supported\n"); in mei_cl_notify_get()
1621 if (!mei_cl_is_connected(cl)) in mei_cl_notify_get()
1624 if (cl->notify_ev) in mei_cl_notify_get()
1631 rets = wait_event_interruptible(cl->ev_wait, cl->notify_ev); in mei_cl_notify_get()
1638 *notify_ev = cl->notify_ev; in mei_cl_notify_get()
1639 cl->notify_ev = false; in mei_cl_notify_get()
1652 int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp) in mei_cl_read_start() argument
1658 if (WARN_ON(!cl || !cl->dev)) in mei_cl_read_start()
1661 dev = cl->dev; in mei_cl_read_start()
1663 if (!mei_cl_is_connected(cl)) in mei_cl_read_start()
1666 if (!mei_me_cl_is_active(cl->me_cl)) { in mei_cl_read_start()
1667 cl_err(dev, cl, "no such me client\n"); in mei_cl_read_start()
1671 if (mei_cl_is_fixed_address(cl)) in mei_cl_read_start()
1675 if (cl->rx_flow_ctrl_creds) { in mei_cl_read_start()
1676 mei_cl_set_read_by_fp(cl, fp); in mei_cl_read_start()
1680 cb = mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, fp); in mei_cl_read_start()
1684 mei_cl_set_read_by_fp(cl, fp); in mei_cl_read_start()
1689 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_read_start()
1695 rets = mei_hbm_cl_flow_control_req(dev, cl); in mei_cl_read_start()
1699 list_move_tail(&cb->list, &cl->rd_pending); in mei_cl_read_start()
1701 cl->rx_flow_ctrl_creds++; in mei_cl_read_start()
1704 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_read_start()
1756 is_hbm = cb->cl->me_cl->client_id == 0; in mei_msg_hdr_init()
1757 is_gsc = ((!is_hbm) && cb->cl->dev->hbm_f_gsc_supported && mei_ext_hdr_is_gsc(cb->ext_hdr)); in mei_msg_hdr_init()
1778 mei_hdr->host_addr = mei_cl_host_addr(cb->cl); in mei_msg_hdr_init()
1779 mei_hdr->me_addr = mei_cl_me_id(cb->cl); in mei_msg_hdr_init()
1816 int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_write() argument
1833 if (WARN_ON(!cl || !cl->dev)) in mei_cl_irq_write()
1836 dev = cl->dev; in mei_cl_irq_write()
1842 rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1; in mei_cl_irq_write()
1847 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_irq_write()
1907 cl->status = 0; in mei_cl_irq_write()
1908 cl->writing_state = MEI_WRITING; in mei_cl_irq_write()
1912 if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) { in mei_cl_irq_write()
1926 cl->status = rets; in mei_cl_irq_write()
1943 ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long timeout) in mei_cl_write() argument
1959 if (WARN_ON(!cl || !cl->dev)) in mei_cl_write()
1965 dev = cl->dev; in mei_cl_write()
1970 cl_dbg(dev, cl, "buf_len=%zd\n", buf_len); in mei_cl_write()
1978 cl_err(dev, cl, "rpm: get failed %zd\n", rets); in mei_cl_write()
1983 cl->writing_state = MEI_IDLE; in mei_cl_write()
1986 rets = mei_cl_tx_flow_ctrl_creds(cl); in mei_cl_write()
2000 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_write()
2006 cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n"); in mei_cl_write()
2048 rets = mei_cl_tx_flow_ctrl_creds_reduce(cl); in mei_cl_write()
2052 cl->writing_state = MEI_WRITING; in mei_cl_write()
2064 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2067 rets = wait_event_interruptible_timeout(cl->tx_wait, in mei_cl_write()
2068 cl->writing_state == MEI_WRITE_COMPLETE || in mei_cl_write()
2069 (!mei_cl_is_connected(cl)), in mei_cl_write()
2075 mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); in mei_cl_write()
2076 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); in mei_cl_write()
2086 if (cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2094 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_write()
2111 void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_complete() argument
2113 struct mei_device *dev = cl->dev; in mei_cl_complete()
2118 cl->writing_state = MEI_WRITE_COMPLETE; in mei_cl_complete()
2119 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_complete()
2120 wake_up_interruptible(&cl->tx_wait); in mei_cl_complete()
2128 mei_cl_add_rd_completed(cl, cb); in mei_cl_complete()
2129 if (!mei_cl_is_fixed_address(cl) && in mei_cl_complete()
2130 !WARN_ON(!cl->rx_flow_ctrl_creds)) in mei_cl_complete()
2131 cl->rx_flow_ctrl_creds--; in mei_cl_complete()
2132 if (!mei_cl_bus_rx_event(cl)) in mei_cl_complete()
2133 wake_up_interruptible(&cl->rx_wait); in mei_cl_complete()
2142 if (waitqueue_active(&cl->wait)) in mei_cl_complete()
2143 wake_up(&cl->wait); in mei_cl_complete()
2148 mei_cl_set_disconnected(cl); in mei_cl_complete()
2163 struct mei_cl *cl; in mei_cl_all_disconnect() local
2165 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_all_disconnect()
2166 mei_cl_set_disconnected(cl); in mei_cl_all_disconnect()
2172 struct mei_cl *cl; in mei_cl_dma_map_find() local
2174 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_dma_map_find()
2175 if (cl->dma.buffer_id == buffer_id) in mei_cl_dma_map_find()
2176 return cl; in mei_cl_dma_map_find()
2189 int mei_cl_irq_dma_map(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_dma_map() argument
2192 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_map()
2205 ret = mei_hbm_cl_dma_map_req(dev, cl); in mei_cl_irq_dma_map()
2207 cl->status = ret; in mei_cl_irq_dma_map()
2225 int mei_cl_irq_dma_unmap(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_dma_unmap() argument
2228 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_unmap()
2241 ret = mei_hbm_cl_dma_unmap_req(dev, cl); in mei_cl_irq_dma_unmap()
2243 cl->status = ret; in mei_cl_irq_dma_unmap()
2252 static int mei_cl_dma_alloc(struct mei_cl *cl, u8 buf_id, size_t size) in mei_cl_dma_alloc() argument
2254 cl->dma.vaddr = dmam_alloc_coherent(cl->dev->dev, size, in mei_cl_dma_alloc()
2255 &cl->dma.daddr, GFP_KERNEL); in mei_cl_dma_alloc()
2256 if (!cl->dma.vaddr) in mei_cl_dma_alloc()
2259 cl->dma.buffer_id = buf_id; in mei_cl_dma_alloc()
2260 cl->dma.size = size; in mei_cl_dma_alloc()
2265 static void mei_cl_dma_free(struct mei_cl *cl) in mei_cl_dma_free() argument
2267 cl->dma.buffer_id = 0; in mei_cl_dma_free()
2268 dmam_free_coherent(cl->dev->dev, in mei_cl_dma_free()
2269 cl->dma.size, cl->dma.vaddr, cl->dma.daddr); in mei_cl_dma_free()
2270 cl->dma.size = 0; in mei_cl_dma_free()
2271 cl->dma.vaddr = NULL; in mei_cl_dma_free()
2272 cl->dma.daddr = 0; in mei_cl_dma_free()
2292 int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp, in mei_cl_dma_alloc_and_map() argument
2299 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_alloc_and_map()
2302 dev = cl->dev; in mei_cl_dma_alloc_and_map()
2305 cl_dbg(dev, cl, "client dma is not supported\n"); in mei_cl_dma_alloc_and_map()
2312 if (mei_cl_is_connected(cl)) in mei_cl_dma_alloc_and_map()
2315 if (cl->dma_mapped) in mei_cl_dma_alloc_and_map()
2319 cl_dbg(dev, cl, "client dma with id %d is already allocated\n", in mei_cl_dma_alloc_and_map()
2320 cl->dma.buffer_id); in mei_cl_dma_alloc_and_map()
2327 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_dma_alloc_and_map()
2331 rets = mei_cl_dma_alloc(cl, buffer_id, size); in mei_cl_dma_alloc_and_map()
2337 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DMA_MAP, fp); in mei_cl_dma_alloc_and_map()
2344 if (mei_hbm_cl_dma_map_req(dev, cl)) { in mei_cl_dma_alloc_and_map()
2351 cl->status = 0; in mei_cl_dma_alloc_and_map()
2354 wait_event_timeout(cl->wait, in mei_cl_dma_alloc_and_map()
2355 cl->dma_mapped || cl->status, in mei_cl_dma_alloc_and_map()
2359 if (!cl->dma_mapped && !cl->status) in mei_cl_dma_alloc_and_map()
2360 cl->status = -EFAULT; in mei_cl_dma_alloc_and_map()
2362 rets = cl->status; in mei_cl_dma_alloc_and_map()
2366 mei_cl_dma_free(cl); in mei_cl_dma_alloc_and_map()
2368 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_alloc_and_map()
2386 int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp) in mei_cl_dma_unmap() argument
2392 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_unmap()
2395 dev = cl->dev; in mei_cl_dma_unmap()
2398 cl_dbg(dev, cl, "client dma is not supported\n"); in mei_cl_dma_unmap()
2403 if (mei_cl_is_connected(cl)) in mei_cl_dma_unmap()
2406 if (!cl->dma_mapped) in mei_cl_dma_unmap()
2412 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_dma_unmap()
2416 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DMA_UNMAP, fp); in mei_cl_dma_unmap()
2423 if (mei_hbm_cl_dma_unmap_req(dev, cl)) { in mei_cl_dma_unmap()
2430 cl->status = 0; in mei_cl_dma_unmap()
2433 wait_event_timeout(cl->wait, in mei_cl_dma_unmap()
2434 !cl->dma_mapped || cl->status, in mei_cl_dma_unmap()
2438 if (cl->dma_mapped && !cl->status) in mei_cl_dma_unmap()
2439 cl->status = -EFAULT; in mei_cl_dma_unmap()
2441 rets = cl->status; in mei_cl_dma_unmap()
2444 mei_cl_dma_free(cl); in mei_cl_dma_unmap()
2446 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_unmap()