Lines Matching refs:cl
340 cb->cl->tx_cb_queued++; in mei_tx_cb_enqueue()
352 if (!WARN_ON(cb->cl->tx_cb_queued == 0)) in mei_tx_cb_dequeue()
353 cb->cl->tx_cb_queued--; in mei_tx_cb_dequeue()
366 static void mei_cl_set_read_by_fp(const struct mei_cl *cl, in mei_cl_set_read_by_fp() argument
371 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_set_read_by_fp()
388 static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, in mei_io_cb_init() argument
400 cb->cl = cl; in mei_io_cb_init()
415 const struct mei_cl *cl) in mei_io_list_flush_cl() argument
420 if (cl == cb->cl) { in mei_io_list_flush_cl()
436 const struct mei_cl *cl, in mei_io_tx_list_free_cl() argument
442 if (cl == cb->cl && (!fp || fp == cb->fp)) in mei_io_tx_list_free_cl()
467 static void mei_cl_free_pending(struct mei_cl *cl) in mei_cl_free_pending() argument
471 cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); in mei_cl_free_pending()
485 struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, in mei_cl_alloc_cb() argument
491 cb = mei_io_cb_init(cl, fop_type, fp); in mei_cl_alloc_cb()
520 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
528 length = max_t(size_t, length, mei_cl_mtu(cl)); in mei_cl_enqueue_ctrl_wr_cb()
530 cb = mei_cl_alloc_cb(cl, length, fop_type, fp); in mei_cl_enqueue_ctrl_wr_cb()
534 list_add_tail(&cb->list, &cl->dev->ctrl_wr_list); in mei_cl_enqueue_ctrl_wr_cb()
547 struct mei_cl_cb *mei_cl_read_cb(struct mei_cl *cl, const struct file *fp) in mei_cl_read_cb() argument
552 spin_lock(&cl->rd_completed_lock); in mei_cl_read_cb()
553 list_for_each_entry(cb, &cl->rd_completed, list) in mei_cl_read_cb()
558 spin_unlock(&cl->rd_completed_lock); in mei_cl_read_cb()
570 int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp) in mei_cl_flush_queues() argument
574 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flush_queues()
577 dev = cl->dev; in mei_cl_flush_queues()
579 cl_dbg(dev, cl, "remove list entry belonging to cl\n"); in mei_cl_flush_queues()
580 mei_io_tx_list_free_cl(&cl->dev->write_list, cl, fp); in mei_cl_flush_queues()
581 mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl, fp); in mei_cl_flush_queues()
584 mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl); in mei_cl_flush_queues()
585 mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl); in mei_cl_flush_queues()
586 mei_cl_free_pending(cl); in mei_cl_flush_queues()
588 spin_lock(&cl->rd_completed_lock); in mei_cl_flush_queues()
589 mei_io_list_free_fp(&cl->rd_completed, fp); in mei_cl_flush_queues()
590 spin_unlock(&cl->rd_completed_lock); in mei_cl_flush_queues()
601 static void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) in mei_cl_init() argument
603 memset(cl, 0, sizeof(*cl)); in mei_cl_init()
604 init_waitqueue_head(&cl->wait); in mei_cl_init()
605 init_waitqueue_head(&cl->rx_wait); in mei_cl_init()
606 init_waitqueue_head(&cl->tx_wait); in mei_cl_init()
607 init_waitqueue_head(&cl->ev_wait); in mei_cl_init()
608 INIT_LIST_HEAD(&cl->vtag_map); in mei_cl_init()
609 spin_lock_init(&cl->rd_completed_lock); in mei_cl_init()
610 INIT_LIST_HEAD(&cl->rd_completed); in mei_cl_init()
611 INIT_LIST_HEAD(&cl->rd_pending); in mei_cl_init()
612 INIT_LIST_HEAD(&cl->link); in mei_cl_init()
613 cl->writing_state = MEI_IDLE; in mei_cl_init()
614 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_init()
615 cl->dev = dev; in mei_cl_init()
626 struct mei_cl *cl; in mei_cl_allocate() local
628 cl = kmalloc(sizeof(*cl), GFP_KERNEL); in mei_cl_allocate()
629 if (!cl) in mei_cl_allocate()
632 mei_cl_init(cl, dev); in mei_cl_allocate()
634 return cl; in mei_cl_allocate()
646 int mei_cl_link(struct mei_cl *cl) in mei_cl_link() argument
651 if (WARN_ON(!cl || !cl->dev)) in mei_cl_link()
654 dev = cl->dev; in mei_cl_link()
670 cl->host_client_id = id; in mei_cl_link()
671 list_add_tail(&cl->link, &dev->file_list); in mei_cl_link()
675 cl->state = MEI_FILE_INITIALIZING; in mei_cl_link()
677 cl_dbg(dev, cl, "link cl\n"); in mei_cl_link()
688 int mei_cl_unlink(struct mei_cl *cl) in mei_cl_unlink() argument
693 if (!cl) in mei_cl_unlink()
696 if (WARN_ON(!cl->dev)) in mei_cl_unlink()
699 dev = cl->dev; in mei_cl_unlink()
701 cl_dbg(dev, cl, "unlink client"); in mei_cl_unlink()
703 if (cl->state == MEI_FILE_UNINITIALIZED) in mei_cl_unlink()
710 if (cl->host_client_id) in mei_cl_unlink()
711 clear_bit(cl->host_client_id, dev->host_clients_map); in mei_cl_unlink()
713 list_del_init(&cl->link); in mei_cl_unlink()
715 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_unlink()
716 cl->writing_state = MEI_IDLE; in mei_cl_unlink()
718 WARN_ON(!list_empty(&cl->rd_completed) || in mei_cl_unlink()
719 !list_empty(&cl->rd_pending) || in mei_cl_unlink()
720 !list_empty(&cl->link)); in mei_cl_unlink()
767 static void mei_cl_wake_all(struct mei_cl *cl) in mei_cl_wake_all() argument
769 struct mei_device *dev = cl->dev; in mei_cl_wake_all()
772 if (waitqueue_active(&cl->rx_wait)) { in mei_cl_wake_all()
773 cl_dbg(dev, cl, "Waking up reading client!\n"); in mei_cl_wake_all()
774 wake_up_interruptible(&cl->rx_wait); in mei_cl_wake_all()
777 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_wake_all()
778 cl_dbg(dev, cl, "Waking up writing client!\n"); in mei_cl_wake_all()
779 wake_up_interruptible(&cl->tx_wait); in mei_cl_wake_all()
782 if (waitqueue_active(&cl->ev_wait)) { in mei_cl_wake_all()
783 cl_dbg(dev, cl, "Waking up waiting for event clients!\n"); in mei_cl_wake_all()
784 wake_up_interruptible(&cl->ev_wait); in mei_cl_wake_all()
787 if (waitqueue_active(&cl->wait)) { in mei_cl_wake_all()
788 cl_dbg(dev, cl, "Waking up ctrl write clients!\n"); in mei_cl_wake_all()
789 wake_up(&cl->wait); in mei_cl_wake_all()
799 static void mei_cl_set_disconnected(struct mei_cl *cl) in mei_cl_set_disconnected() argument
801 struct mei_device *dev = cl->dev; in mei_cl_set_disconnected()
803 if (cl->state == MEI_FILE_DISCONNECTED || in mei_cl_set_disconnected()
804 cl->state <= MEI_FILE_INITIALIZING) in mei_cl_set_disconnected()
807 cl->state = MEI_FILE_DISCONNECTED; in mei_cl_set_disconnected()
808 mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); in mei_cl_set_disconnected()
809 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); in mei_cl_set_disconnected()
810 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_set_disconnected()
811 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_set_disconnected()
812 mei_cl_wake_all(cl); in mei_cl_set_disconnected()
813 cl->rx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
814 cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
815 cl->timer_count = 0; in mei_cl_set_disconnected()
817 if (!cl->me_cl) in mei_cl_set_disconnected()
820 if (!WARN_ON(cl->me_cl->connect_count == 0)) in mei_cl_set_disconnected()
821 cl->me_cl->connect_count--; in mei_cl_set_disconnected()
823 if (cl->me_cl->connect_count == 0) in mei_cl_set_disconnected()
824 cl->me_cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
826 mei_me_cl_put(cl->me_cl); in mei_cl_set_disconnected()
827 cl->me_cl = NULL; in mei_cl_set_disconnected()
830 static int mei_cl_set_connecting(struct mei_cl *cl, struct mei_me_client *me_cl) in mei_cl_set_connecting() argument
843 cl->me_cl = me_cl; in mei_cl_set_connecting()
844 cl->state = MEI_FILE_CONNECTING; in mei_cl_set_connecting()
845 cl->me_cl->connect_count++; in mei_cl_set_connecting()
858 static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_send_disconnect() argument
863 dev = cl->dev; in mei_cl_send_disconnect()
865 ret = mei_hbm_cl_disconnect_req(dev, cl); in mei_cl_send_disconnect()
866 cl->status = ret; in mei_cl_send_disconnect()
868 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_disconnect()
873 cl->timer_count = dev->timeouts.connect; in mei_cl_send_disconnect()
889 int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_disconnect() argument
892 struct mei_device *dev = cl->dev; in mei_cl_irq_disconnect()
905 ret = mei_cl_send_disconnect(cl, cb); in mei_cl_irq_disconnect()
920 static int __mei_cl_disconnect(struct mei_cl *cl) in __mei_cl_disconnect() argument
926 dev = cl->dev; in __mei_cl_disconnect()
928 cl->state = MEI_FILE_DISCONNECTING; in __mei_cl_disconnect()
930 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT, NULL); in __mei_cl_disconnect()
937 rets = mei_cl_send_disconnect(cl, cb); in __mei_cl_disconnect()
939 cl_err(dev, cl, "failed to disconnect.\n"); in __mei_cl_disconnect()
945 wait_event_timeout(cl->wait, in __mei_cl_disconnect()
946 cl->state == MEI_FILE_DISCONNECT_REPLY || in __mei_cl_disconnect()
947 cl->state == MEI_FILE_DISCONNECTED, in __mei_cl_disconnect()
951 rets = cl->status; in __mei_cl_disconnect()
952 if (cl->state != MEI_FILE_DISCONNECT_REPLY && in __mei_cl_disconnect()
953 cl->state != MEI_FILE_DISCONNECTED) { in __mei_cl_disconnect()
954 cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); in __mei_cl_disconnect()
960 mei_cl_set_disconnected(cl); in __mei_cl_disconnect()
962 cl_dbg(dev, cl, "successfully disconnected from FW client.\n"); in __mei_cl_disconnect()
977 int mei_cl_disconnect(struct mei_cl *cl) in mei_cl_disconnect() argument
982 if (WARN_ON(!cl || !cl->dev)) in mei_cl_disconnect()
985 dev = cl->dev; in mei_cl_disconnect()
987 cl_dbg(dev, cl, "disconnecting"); in mei_cl_disconnect()
989 if (!mei_cl_is_connected(cl)) in mei_cl_disconnect()
992 if (mei_cl_is_fixed_address(cl)) { in mei_cl_disconnect()
993 mei_cl_set_disconnected(cl); in mei_cl_disconnect()
999 cl_dbg(dev, cl, "Device is powering down, don't bother with disconnection\n"); in mei_cl_disconnect()
1000 mei_cl_set_disconnected(cl); in mei_cl_disconnect()
1007 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_disconnect()
1011 rets = __mei_cl_disconnect(cl); in mei_cl_disconnect()
1013 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_disconnect()
1029 static bool mei_cl_is_other_connecting(struct mei_cl *cl) in mei_cl_is_other_connecting() argument
1034 dev = cl->dev; in mei_cl_is_other_connecting()
1038 mei_cl_me_id(cl) == mei_cl_me_id(cb->cl)) in mei_cl_is_other_connecting()
1053 static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_send_connect() argument
1058 dev = cl->dev; in mei_cl_send_connect()
1060 ret = mei_hbm_cl_connect_req(dev, cl); in mei_cl_send_connect()
1061 cl->status = ret; in mei_cl_send_connect()
1063 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_connect()
1068 cl->timer_count = dev->timeouts.connect; in mei_cl_send_connect()
1082 int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_connect() argument
1085 struct mei_device *dev = cl->dev; in mei_cl_irq_connect()
1090 if (mei_cl_is_other_connecting(cl)) in mei_cl_irq_connect()
1101 rets = mei_cl_send_connect(cl, cb); in mei_cl_irq_connect()
1119 int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, in mei_cl_connect() argument
1126 if (WARN_ON(!cl || !cl->dev || !me_cl)) in mei_cl_connect()
1129 dev = cl->dev; in mei_cl_connect()
1131 rets = mei_cl_set_connecting(cl, me_cl); in mei_cl_connect()
1135 if (mei_cl_is_fixed_address(cl)) { in mei_cl_connect()
1136 cl->state = MEI_FILE_CONNECTED; in mei_cl_connect()
1144 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_connect()
1148 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_CONNECT, fp); in mei_cl_connect()
1155 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { in mei_cl_connect()
1156 rets = mei_cl_send_connect(cl, cb); in mei_cl_connect()
1162 wait_event_timeout(cl->wait, in mei_cl_connect()
1163 (cl->state == MEI_FILE_CONNECTED || in mei_cl_connect()
1164 cl->state == MEI_FILE_DISCONNECTED || in mei_cl_connect()
1165 cl->state == MEI_FILE_DISCONNECT_REQUIRED || in mei_cl_connect()
1166 cl->state == MEI_FILE_DISCONNECT_REPLY), in mei_cl_connect()
1170 if (!mei_cl_is_connected(cl)) { in mei_cl_connect()
1171 if (cl->state == MEI_FILE_DISCONNECT_REQUIRED) { in mei_cl_connect()
1172 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_connect()
1173 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_connect()
1177 __mei_cl_disconnect(cl); in mei_cl_connect()
1183 if (!cl->status) in mei_cl_connect()
1184 cl->status = -EFAULT; in mei_cl_connect()
1187 rets = cl->status; in mei_cl_connect()
1189 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_connect()
1196 if (!mei_cl_is_connected(cl)) in mei_cl_connect()
1197 mei_cl_set_disconnected(cl); in mei_cl_connect()
1211 struct mei_cl *cl; in mei_cl_alloc_linked() local
1214 cl = mei_cl_allocate(dev); in mei_cl_alloc_linked()
1215 if (!cl) { in mei_cl_alloc_linked()
1220 ret = mei_cl_link(cl); in mei_cl_alloc_linked()
1224 return cl; in mei_cl_alloc_linked()
1226 kfree(cl); in mei_cl_alloc_linked()
1237 static int mei_cl_tx_flow_ctrl_creds(struct mei_cl *cl) in mei_cl_tx_flow_ctrl_creds() argument
1239 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds()
1242 if (cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1245 if (mei_cl_is_fixed_address(cl)) in mei_cl_tx_flow_ctrl_creds()
1248 if (mei_cl_is_single_recv_buf(cl)) { in mei_cl_tx_flow_ctrl_creds()
1249 if (cl->me_cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1265 static int mei_cl_tx_flow_ctrl_creds_reduce(struct mei_cl *cl) in mei_cl_tx_flow_ctrl_creds_reduce() argument
1267 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds_reduce()
1270 if (mei_cl_is_fixed_address(cl)) in mei_cl_tx_flow_ctrl_creds_reduce()
1273 if (mei_cl_is_single_recv_buf(cl)) { in mei_cl_tx_flow_ctrl_creds_reduce()
1274 if (WARN_ON(cl->me_cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1276 cl->me_cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1278 if (WARN_ON(cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1280 cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1320 const struct file *mei_cl_fp_by_vtag(const struct mei_cl *cl, u8 vtag) in mei_cl_fp_by_vtag() argument
1324 list_for_each_entry(vtag_l, &cl->vtag_map, list) in mei_cl_fp_by_vtag()
1326 if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || in mei_cl_fp_by_vtag()
1339 static void mei_cl_reset_read_by_vtag(const struct mei_cl *cl, u8 vtag) in mei_cl_reset_read_by_vtag() argument
1343 list_for_each_entry(vtag_l, &cl->vtag_map, list) { in mei_cl_reset_read_by_vtag()
1357 static void mei_cl_read_vtag_add_fc(struct mei_cl *cl) in mei_cl_read_vtag_add_fc() argument
1361 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_read_vtag_add_fc()
1363 if (mei_cl_enqueue_ctrl_wr_cb(cl, in mei_cl_read_vtag_add_fc()
1364 mei_cl_mtu(cl), in mei_cl_read_vtag_add_fc()
1367 cl->rx_flow_ctrl_creds++; in mei_cl_read_vtag_add_fc()
1382 int mei_cl_vt_support_check(const struct mei_cl *cl) in mei_cl_vt_support_check() argument
1384 struct mei_device *dev = cl->dev; in mei_cl_vt_support_check()
1389 if (!cl->me_cl) in mei_cl_vt_support_check()
1392 return cl->me_cl->props.vt_supported ? 0 : -EOPNOTSUPP; in mei_cl_vt_support_check()
1403 void mei_cl_add_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_add_rd_completed() argument
1407 if (!mei_cl_vt_support_check(cl)) { in mei_cl_add_rd_completed()
1408 fp = mei_cl_fp_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1415 mei_cl_reset_read_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1416 mei_cl_read_vtag_add_fc(cl); in mei_cl_add_rd_completed()
1419 spin_lock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1420 list_add_tail(&cb->list, &cl->rd_completed); in mei_cl_add_rd_completed()
1421 spin_unlock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1431 void mei_cl_del_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_del_rd_completed() argument
1433 spin_lock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1435 spin_unlock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1477 int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_notify() argument
1480 struct mei_device *dev = cl->dev; in mei_cl_irq_notify()
1495 ret = mei_hbm_cl_notify_req(dev, cl, request); in mei_cl_irq_notify()
1497 cl->status = ret; in mei_cl_irq_notify()
1517 int mei_cl_notify_request(struct mei_cl *cl, in mei_cl_notify_request() argument
1525 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_request()
1528 dev = cl->dev; in mei_cl_notify_request()
1531 cl_dbg(dev, cl, "notifications not supported\n"); in mei_cl_notify_request()
1535 if (!mei_cl_is_connected(cl)) in mei_cl_notify_request()
1541 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_notify_request()
1546 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, fop_type, fp); in mei_cl_notify_request()
1553 if (mei_hbm_cl_notify_req(dev, cl, request)) { in mei_cl_notify_request()
1561 wait_event_timeout(cl->wait, in mei_cl_notify_request()
1562 cl->notify_en == request || in mei_cl_notify_request()
1563 cl->status || in mei_cl_notify_request()
1564 !mei_cl_is_connected(cl), in mei_cl_notify_request()
1568 if (cl->notify_en != request && !cl->status) in mei_cl_notify_request()
1569 cl->status = -EFAULT; in mei_cl_notify_request()
1571 rets = cl->status; in mei_cl_notify_request()
1574 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_notify_request()
1589 void mei_cl_notify(struct mei_cl *cl) in mei_cl_notify() argument
1593 if (!cl || !cl->dev) in mei_cl_notify()
1596 dev = cl->dev; in mei_cl_notify()
1598 if (!cl->notify_en) in mei_cl_notify()
1601 cl_dbg(dev, cl, "notify event"); in mei_cl_notify()
1602 cl->notify_ev = true; in mei_cl_notify()
1603 if (!mei_cl_bus_notify_event(cl)) in mei_cl_notify()
1604 wake_up_interruptible(&cl->ev_wait); in mei_cl_notify()
1606 if (cl->ev_async) in mei_cl_notify()
1607 kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); in mei_cl_notify()
1622 int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev) in mei_cl_notify_get() argument
1629 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_get()
1632 dev = cl->dev; in mei_cl_notify_get()
1635 cl_dbg(dev, cl, "notifications not supported\n"); in mei_cl_notify_get()
1639 if (!mei_cl_is_connected(cl)) in mei_cl_notify_get()
1642 if (cl->notify_ev) in mei_cl_notify_get()
1649 rets = wait_event_interruptible(cl->ev_wait, cl->notify_ev); in mei_cl_notify_get()
1656 *notify_ev = cl->notify_ev; in mei_cl_notify_get()
1657 cl->notify_ev = false; in mei_cl_notify_get()
1670 int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp) in mei_cl_read_start() argument
1676 if (WARN_ON(!cl || !cl->dev)) in mei_cl_read_start()
1679 dev = cl->dev; in mei_cl_read_start()
1681 if (!mei_cl_is_connected(cl)) in mei_cl_read_start()
1684 if (!mei_me_cl_is_active(cl->me_cl)) { in mei_cl_read_start()
1685 cl_err(dev, cl, "no such me client\n"); in mei_cl_read_start()
1689 if (mei_cl_is_fixed_address(cl)) in mei_cl_read_start()
1693 if (cl->rx_flow_ctrl_creds) { in mei_cl_read_start()
1694 mei_cl_set_read_by_fp(cl, fp); in mei_cl_read_start()
1698 cb = mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, fp); in mei_cl_read_start()
1702 mei_cl_set_read_by_fp(cl, fp); in mei_cl_read_start()
1707 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_read_start()
1713 rets = mei_hbm_cl_flow_control_req(dev, cl); in mei_cl_read_start()
1717 list_move_tail(&cb->list, &cl->rd_pending); in mei_cl_read_start()
1719 cl->rx_flow_ctrl_creds++; in mei_cl_read_start()
1722 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_read_start()
1779 mei_hdr->host_addr = mei_cl_host_addr(cb->cl); in mei_msg_hdr_init()
1780 mei_hdr->me_addr = mei_cl_me_id(cb->cl); in mei_msg_hdr_init()
1807 int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_write() argument
1824 if (WARN_ON(!cl || !cl->dev)) in mei_cl_irq_write()
1827 dev = cl->dev; in mei_cl_irq_write()
1833 rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1; in mei_cl_irq_write()
1838 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_irq_write()
1861 cl_dbg(dev, cl, "Extended Header %d vtag = %d\n", in mei_cl_irq_write()
1899 cl->status = 0; in mei_cl_irq_write()
1900 cl->writing_state = MEI_WRITING; in mei_cl_irq_write()
1904 if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) { in mei_cl_irq_write()
1918 cl->status = rets; in mei_cl_irq_write()
1932 ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_write() argument
1948 if (WARN_ON(!cl || !cl->dev)) in mei_cl_write()
1954 dev = cl->dev; in mei_cl_write()
1959 cl_dbg(dev, cl, "buf_len=%zd\n", buf_len); in mei_cl_write()
1967 cl_err(dev, cl, "rpm: get failed %zd\n", rets); in mei_cl_write()
1972 cl->writing_state = MEI_IDLE; in mei_cl_write()
1975 rets = mei_cl_tx_flow_ctrl_creds(cl); in mei_cl_write()
1986 cl_dbg(dev, cl, "Extended Header %d vtag = %d\n", in mei_cl_write()
1992 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_write()
1998 cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n"); in mei_cl_write()
2040 rets = mei_cl_tx_flow_ctrl_creds_reduce(cl); in mei_cl_write()
2044 cl->writing_state = MEI_WRITING; in mei_cl_write()
2056 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2059 rets = wait_event_interruptible(cl->tx_wait, in mei_cl_write()
2060 cl->writing_state == MEI_WRITE_COMPLETE || in mei_cl_write()
2061 (!mei_cl_is_connected(cl))); in mei_cl_write()
2069 if (cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2077 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_write()
2094 void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_complete() argument
2096 struct mei_device *dev = cl->dev; in mei_cl_complete()
2101 cl->writing_state = MEI_WRITE_COMPLETE; in mei_cl_complete()
2102 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_complete()
2103 wake_up_interruptible(&cl->tx_wait); in mei_cl_complete()
2111 mei_cl_add_rd_completed(cl, cb); in mei_cl_complete()
2112 if (!mei_cl_is_fixed_address(cl) && in mei_cl_complete()
2113 !WARN_ON(!cl->rx_flow_ctrl_creds)) in mei_cl_complete()
2114 cl->rx_flow_ctrl_creds--; in mei_cl_complete()
2115 if (!mei_cl_bus_rx_event(cl)) in mei_cl_complete()
2116 wake_up_interruptible(&cl->rx_wait); in mei_cl_complete()
2125 if (waitqueue_active(&cl->wait)) in mei_cl_complete()
2126 wake_up(&cl->wait); in mei_cl_complete()
2131 mei_cl_set_disconnected(cl); in mei_cl_complete()
2146 struct mei_cl *cl; in mei_cl_all_disconnect() local
2148 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_all_disconnect()
2149 mei_cl_set_disconnected(cl); in mei_cl_all_disconnect()
2155 struct mei_cl *cl; in mei_cl_dma_map_find() local
2157 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_dma_map_find()
2158 if (cl->dma.buffer_id == buffer_id) in mei_cl_dma_map_find()
2159 return cl; in mei_cl_dma_map_find()
2172 int mei_cl_irq_dma_map(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_dma_map() argument
2175 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_map()
2188 ret = mei_hbm_cl_dma_map_req(dev, cl); in mei_cl_irq_dma_map()
2190 cl->status = ret; in mei_cl_irq_dma_map()
2208 int mei_cl_irq_dma_unmap(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_dma_unmap() argument
2211 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_unmap()
2224 ret = mei_hbm_cl_dma_unmap_req(dev, cl); in mei_cl_irq_dma_unmap()
2226 cl->status = ret; in mei_cl_irq_dma_unmap()
2235 static int mei_cl_dma_alloc(struct mei_cl *cl, u8 buf_id, size_t size) in mei_cl_dma_alloc() argument
2237 cl->dma.vaddr = dmam_alloc_coherent(cl->dev->dev, size, in mei_cl_dma_alloc()
2238 &cl->dma.daddr, GFP_KERNEL); in mei_cl_dma_alloc()
2239 if (!cl->dma.vaddr) in mei_cl_dma_alloc()
2242 cl->dma.buffer_id = buf_id; in mei_cl_dma_alloc()
2243 cl->dma.size = size; in mei_cl_dma_alloc()
2248 static void mei_cl_dma_free(struct mei_cl *cl) in mei_cl_dma_free() argument
2250 cl->dma.buffer_id = 0; in mei_cl_dma_free()
2251 dmam_free_coherent(cl->dev->dev, in mei_cl_dma_free()
2252 cl->dma.size, cl->dma.vaddr, cl->dma.daddr); in mei_cl_dma_free()
2253 cl->dma.size = 0; in mei_cl_dma_free()
2254 cl->dma.vaddr = NULL; in mei_cl_dma_free()
2255 cl->dma.daddr = 0; in mei_cl_dma_free()
2275 int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp, in mei_cl_dma_alloc_and_map() argument
2282 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_alloc_and_map()
2285 dev = cl->dev; in mei_cl_dma_alloc_and_map()
2288 cl_dbg(dev, cl, "client dma is not supported\n"); in mei_cl_dma_alloc_and_map()
2295 if (mei_cl_is_connected(cl)) in mei_cl_dma_alloc_and_map()
2298 if (cl->dma_mapped) in mei_cl_dma_alloc_and_map()
2302 cl_dbg(dev, cl, "client dma with id %d is already allocated\n", in mei_cl_dma_alloc_and_map()
2303 cl->dma.buffer_id); in mei_cl_dma_alloc_and_map()
2310 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_dma_alloc_and_map()
2314 rets = mei_cl_dma_alloc(cl, buffer_id, size); in mei_cl_dma_alloc_and_map()
2320 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DMA_MAP, fp); in mei_cl_dma_alloc_and_map()
2327 if (mei_hbm_cl_dma_map_req(dev, cl)) { in mei_cl_dma_alloc_and_map()
2334 cl->status = 0; in mei_cl_dma_alloc_and_map()
2337 wait_event_timeout(cl->wait, in mei_cl_dma_alloc_and_map()
2338 cl->dma_mapped || cl->status, in mei_cl_dma_alloc_and_map()
2342 if (!cl->dma_mapped && !cl->status) in mei_cl_dma_alloc_and_map()
2343 cl->status = -EFAULT; in mei_cl_dma_alloc_and_map()
2345 rets = cl->status; in mei_cl_dma_alloc_and_map()
2349 mei_cl_dma_free(cl); in mei_cl_dma_alloc_and_map()
2351 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_alloc_and_map()
2369 int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp) in mei_cl_dma_unmap() argument
2375 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_unmap()
2378 dev = cl->dev; in mei_cl_dma_unmap()
2381 cl_dbg(dev, cl, "client dma is not supported\n"); in mei_cl_dma_unmap()
2386 if (mei_cl_is_connected(cl)) in mei_cl_dma_unmap()
2389 if (!cl->dma_mapped) in mei_cl_dma_unmap()
2395 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_dma_unmap()
2399 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DMA_UNMAP, fp); in mei_cl_dma_unmap()
2406 if (mei_hbm_cl_dma_unmap_req(dev, cl)) { in mei_cl_dma_unmap()
2413 cl->status = 0; in mei_cl_dma_unmap()
2416 wait_event_timeout(cl->wait, in mei_cl_dma_unmap()
2417 !cl->dma_mapped || cl->status, in mei_cl_dma_unmap()
2421 if (cl->dma_mapped && !cl->status) in mei_cl_dma_unmap()
2422 cl->status = -EFAULT; in mei_cl_dma_unmap()
2424 rets = cl->status; in mei_cl_dma_unmap()
2427 mei_cl_dma_free(cl); in mei_cl_dma_unmap()
2429 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_unmap()