Lines Matching refs:cl
347 struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, in mei_io_cb_init() argument
358 cb->cl = cl; in mei_io_cb_init()
372 struct mei_cl *cl, bool free) in __mei_io_list_flush() argument
378 if (!cl || mei_cl_cmp_id(cl, cb->cl)) { in __mei_io_list_flush()
392 void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) in mei_io_list_flush() argument
394 __mei_io_list_flush(list, cl, false); in mei_io_list_flush()
403 static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl) in mei_io_list_free() argument
405 __mei_io_list_flush(list, cl, true); in mei_io_list_free()
443 struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, in mei_cl_alloc_cb() argument
448 cb = mei_io_cb_init(cl, type, fp); in mei_cl_alloc_cb()
469 struct mei_cl_cb *mei_cl_read_cb(const struct mei_cl *cl, const struct file *fp) in mei_cl_read_cb() argument
473 list_for_each_entry(cb, &cl->rd_completed, list) in mei_cl_read_cb()
487 void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp) in mei_cl_read_cb_flush() argument
491 list_for_each_entry_safe(cb, next, &cl->rd_completed, list) in mei_cl_read_cb_flush()
496 list_for_each_entry_safe(cb, next, &cl->rd_pending, list) in mei_cl_read_cb_flush()
509 int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp) in mei_cl_flush_queues() argument
513 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flush_queues()
516 dev = cl->dev; in mei_cl_flush_queues()
518 cl_dbg(dev, cl, "remove list entry belonging to cl\n"); in mei_cl_flush_queues()
519 mei_io_list_free(&cl->dev->write_list, cl); in mei_cl_flush_queues()
520 mei_io_list_free(&cl->dev->write_waiting_list, cl); in mei_cl_flush_queues()
521 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); in mei_cl_flush_queues()
522 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); in mei_cl_flush_queues()
523 mei_io_list_flush(&cl->dev->amthif_cmd_list, cl); in mei_cl_flush_queues()
524 mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl); in mei_cl_flush_queues()
526 mei_cl_read_cb_flush(cl, fp); in mei_cl_flush_queues()
538 void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) in mei_cl_init() argument
540 memset(cl, 0, sizeof(struct mei_cl)); in mei_cl_init()
541 init_waitqueue_head(&cl->wait); in mei_cl_init()
542 init_waitqueue_head(&cl->rx_wait); in mei_cl_init()
543 init_waitqueue_head(&cl->tx_wait); in mei_cl_init()
544 INIT_LIST_HEAD(&cl->rd_completed); in mei_cl_init()
545 INIT_LIST_HEAD(&cl->rd_pending); in mei_cl_init()
546 INIT_LIST_HEAD(&cl->link); in mei_cl_init()
547 INIT_LIST_HEAD(&cl->device_link); in mei_cl_init()
548 cl->writing_state = MEI_IDLE; in mei_cl_init()
549 cl->dev = dev; in mei_cl_init()
560 struct mei_cl *cl; in mei_cl_allocate() local
562 cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); in mei_cl_allocate()
563 if (!cl) in mei_cl_allocate()
566 mei_cl_init(cl, dev); in mei_cl_allocate()
568 return cl; in mei_cl_allocate()
581 int mei_cl_link(struct mei_cl *cl, int id) in mei_cl_link() argument
586 if (WARN_ON(!cl || !cl->dev)) in mei_cl_link()
589 dev = cl->dev; in mei_cl_link()
610 cl->host_client_id = id; in mei_cl_link()
611 list_add_tail(&cl->link, &dev->file_list); in mei_cl_link()
615 cl->state = MEI_FILE_INITIALIZING; in mei_cl_link()
617 cl_dbg(dev, cl, "link cl\n"); in mei_cl_link()
628 int mei_cl_unlink(struct mei_cl *cl) in mei_cl_unlink() argument
633 if (!cl) in mei_cl_unlink()
637 if (!cl->dev) in mei_cl_unlink()
640 dev = cl->dev; in mei_cl_unlink()
642 cl_dbg(dev, cl, "unlink client"); in mei_cl_unlink()
648 if (cl->host_client_id) in mei_cl_unlink()
649 clear_bit(cl->host_client_id, dev->host_clients_map); in mei_cl_unlink()
651 list_del_init(&cl->link); in mei_cl_unlink()
653 cl->state = MEI_FILE_INITIALIZING; in mei_cl_unlink()
726 int mei_cl_disconnect(struct mei_cl *cl) in mei_cl_disconnect() argument
732 if (WARN_ON(!cl || !cl->dev)) in mei_cl_disconnect()
735 dev = cl->dev; in mei_cl_disconnect()
737 cl_dbg(dev, cl, "disconnecting"); in mei_cl_disconnect()
739 if (cl->state != MEI_FILE_DISCONNECTING) in mei_cl_disconnect()
745 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_disconnect()
749 cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT, NULL); in mei_cl_disconnect()
755 if (mei_hbm_cl_disconnect_req(dev, cl)) { in mei_cl_disconnect()
757 cl_err(dev, cl, "failed to disconnect.\n"); in mei_cl_disconnect()
760 cl->timer_count = MEI_CONNECT_TIMEOUT; in mei_cl_disconnect()
764 cl_dbg(dev, cl, "add disconnect cb to control write list\n"); in mei_cl_disconnect()
770 wait_event_timeout(cl->wait, in mei_cl_disconnect()
771 MEI_FILE_DISCONNECTED == cl->state, in mei_cl_disconnect()
776 if (MEI_FILE_DISCONNECTED == cl->state) { in mei_cl_disconnect()
778 cl_dbg(dev, cl, "successfully disconnected from FW client.\n"); in mei_cl_disconnect()
780 cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); in mei_cl_disconnect()
784 mei_io_list_flush(&dev->ctrl_rd_list, cl); in mei_cl_disconnect()
785 mei_io_list_flush(&dev->ctrl_wr_list, cl); in mei_cl_disconnect()
787 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_disconnect()
804 bool mei_cl_is_other_connecting(struct mei_cl *cl) in mei_cl_is_other_connecting() argument
809 if (WARN_ON(!cl || !cl->dev)) in mei_cl_is_other_connecting()
812 dev = cl->dev; in mei_cl_is_other_connecting()
816 ocl != cl && in mei_cl_is_other_connecting()
817 cl->me_client_id == ocl->me_client_id) in mei_cl_is_other_connecting()
835 int mei_cl_connect(struct mei_cl *cl, struct file *file) in mei_cl_connect() argument
841 if (WARN_ON(!cl || !cl->dev)) in mei_cl_connect()
844 dev = cl->dev; in mei_cl_connect()
849 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_connect()
853 cb = mei_io_cb_init(cl, MEI_FOP_CONNECT, file); in mei_cl_connect()
859 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { in mei_cl_connect()
860 cl->state = MEI_FILE_CONNECTING; in mei_cl_connect()
861 if (mei_hbm_cl_connect_req(dev, cl)) { in mei_cl_connect()
865 cl->timer_count = MEI_CONNECT_TIMEOUT; in mei_cl_connect()
868 cl->state = MEI_FILE_INITIALIZING; in mei_cl_connect()
873 wait_event_timeout(cl->wait, in mei_cl_connect()
874 (cl->state == MEI_FILE_CONNECTED || in mei_cl_connect()
875 cl->state == MEI_FILE_DISCONNECTED), in mei_cl_connect()
879 if (!mei_cl_is_connected(cl)) { in mei_cl_connect()
880 cl->state = MEI_FILE_DISCONNECTED; in mei_cl_connect()
882 if (!cl->status) in mei_cl_connect()
883 cl->status = -EFAULT; in mei_cl_connect()
885 mei_io_list_flush(&dev->ctrl_rd_list, cl); in mei_cl_connect()
886 mei_io_list_flush(&dev->ctrl_wr_list, cl); in mei_cl_connect()
889 rets = cl->status; in mei_cl_connect()
892 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_connect()
910 struct mei_cl *cl; in mei_cl_alloc_linked() local
913 cl = mei_cl_allocate(dev); in mei_cl_alloc_linked()
914 if (!cl) { in mei_cl_alloc_linked()
919 ret = mei_cl_link(cl, id); in mei_cl_alloc_linked()
923 return cl; in mei_cl_alloc_linked()
925 kfree(cl); in mei_cl_alloc_linked()
940 int mei_cl_flow_ctrl_creds(struct mei_cl *cl) in mei_cl_flow_ctrl_creds() argument
946 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flow_ctrl_creds()
949 dev = cl->dev; in mei_cl_flow_ctrl_creds()
951 if (cl->mei_flow_ctrl_creds > 0) in mei_cl_flow_ctrl_creds()
954 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); in mei_cl_flow_ctrl_creds()
956 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); in mei_cl_flow_ctrl_creds()
979 int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) in mei_cl_flow_ctrl_reduce() argument
985 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flow_ctrl_reduce()
988 dev = cl->dev; in mei_cl_flow_ctrl_reduce()
990 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); in mei_cl_flow_ctrl_reduce()
992 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); in mei_cl_flow_ctrl_reduce()
1003 if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) { in mei_cl_flow_ctrl_reduce()
1007 cl->mei_flow_ctrl_creds--; in mei_cl_flow_ctrl_reduce()
1024 int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp) in mei_cl_read_start() argument
1031 if (WARN_ON(!cl || !cl->dev)) in mei_cl_read_start()
1034 dev = cl->dev; in mei_cl_read_start()
1036 if (!mei_cl_is_connected(cl)) in mei_cl_read_start()
1040 if (!list_empty(&cl->rd_pending)) in mei_cl_read_start()
1043 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); in mei_cl_read_start()
1045 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); in mei_cl_read_start()
1055 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_read_start()
1059 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp); in mei_cl_read_start()
1065 rets = mei_hbm_cl_flow_control_req(dev, cl); in mei_cl_read_start()
1069 list_add_tail(&cb->list, &cl->rd_pending); in mei_cl_read_start()
1075 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_read_start()
1095 int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, in mei_cl_irq_write() argument
1106 if (WARN_ON(!cl || !cl->dev)) in mei_cl_irq_write()
1109 dev = cl->dev; in mei_cl_irq_write()
1113 rets = mei_cl_flow_ctrl_creds(cl); in mei_cl_irq_write()
1118 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_irq_write()
1126 mei_hdr.host_addr = cl->host_client_id; in mei_cl_irq_write()
1127 mei_hdr.me_addr = cl->me_client_id; in mei_cl_irq_write()
1145 cl_dbg(dev, cl, "buf: size = %d idx = %lu\n", in mei_cl_irq_write()
1150 cl->status = rets; in mei_cl_irq_write()
1155 cl->status = 0; in mei_cl_irq_write()
1156 cl->writing_state = MEI_WRITING; in mei_cl_irq_write()
1161 if (mei_cl_flow_ctrl_reduce(cl)) in mei_cl_irq_write()
1179 int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) in mei_cl_write() argument
1187 if (WARN_ON(!cl || !cl->dev)) in mei_cl_write()
1193 dev = cl->dev; in mei_cl_write()
1198 cl_dbg(dev, cl, "size=%d\n", buf->size); in mei_cl_write()
1203 cl_err(dev, cl, "rpm: get failed %d\n", rets); in mei_cl_write()
1208 cl->writing_state = MEI_IDLE; in mei_cl_write()
1210 mei_hdr.host_addr = cl->host_client_id; in mei_cl_write()
1211 mei_hdr.me_addr = cl->me_client_id; in mei_cl_write()
1216 rets = mei_cl_flow_ctrl_creds(cl); in mei_cl_write()
1221 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); in mei_cl_write()
1226 cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n"); in mei_cl_write()
1244 cl->writing_state = MEI_WRITING; in mei_cl_write()
1250 rets = mei_cl_flow_ctrl_reduce(cl); in mei_cl_write()
1260 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
1263 rets = wait_event_interruptible(cl->tx_wait, in mei_cl_write()
1264 cl->writing_state == MEI_WRITE_COMPLETE); in mei_cl_write()
1276 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_write()
1290 void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) in mei_cl_complete() argument
1295 cl->writing_state = MEI_WRITE_COMPLETE; in mei_cl_complete()
1296 if (waitqueue_active(&cl->tx_wait)) in mei_cl_complete()
1297 wake_up_interruptible(&cl->tx_wait); in mei_cl_complete()
1300 list_add_tail(&cb->list, &cl->rd_completed); in mei_cl_complete()
1301 if (waitqueue_active(&cl->rx_wait)) in mei_cl_complete()
1302 wake_up_interruptible_all(&cl->rx_wait); in mei_cl_complete()
1304 mei_cl_bus_rx_event(cl); in mei_cl_complete()
1318 struct mei_cl *cl; in mei_cl_all_disconnect() local
1320 list_for_each_entry(cl, &dev->file_list, link) { in mei_cl_all_disconnect()
1321 cl->state = MEI_FILE_DISCONNECTED; in mei_cl_all_disconnect()
1322 cl->mei_flow_ctrl_creds = 0; in mei_cl_all_disconnect()
1323 cl->timer_count = 0; in mei_cl_all_disconnect()
1335 struct mei_cl *cl; in mei_cl_all_wakeup() local
1337 list_for_each_entry(cl, &dev->file_list, link) { in mei_cl_all_wakeup()
1338 if (waitqueue_active(&cl->rx_wait)) { in mei_cl_all_wakeup()
1339 cl_dbg(dev, cl, "Waking up reading client!\n"); in mei_cl_all_wakeup()
1340 wake_up_interruptible(&cl->rx_wait); in mei_cl_all_wakeup()
1342 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_all_wakeup()
1343 cl_dbg(dev, cl, "Waking up writing client!\n"); in mei_cl_all_wakeup()
1344 wake_up_interruptible(&cl->tx_wait); in mei_cl_all_wakeup()