Lines Matching refs:mcdi

28 #include "mcdi.h"
39 static void cdx_mcdi_start_or_queue(struct cdx_mcdi_iface *mcdi,
41 static void cdx_mcdi_cmd_start_or_queue(struct cdx_mcdi_iface *mcdi,
43 static bool cdx_mcdi_complete_cmd(struct cdx_mcdi_iface *mcdi,
48 static void cdx_mcdi_timeout_cmd(struct cdx_mcdi_iface *mcdi,
71 static void _cdx_mcdi_remove_cmd(struct cdx_mcdi_iface *mcdi,
81 ++mcdi->outstanding_cleanups;
86 static void cdx_mcdi_remove_cmd(struct cdx_mcdi_iface *mcdi,
91 _cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
94 if (list_empty(&mcdi->cmd_list))
95 wake_up(&mcdi->cmd_complete_wq);
108 struct cdx_mcdi_iface *mcdi;
111 cdx->mcdi = kzalloc(sizeof(*cdx->mcdi), GFP_KERNEL);
112 if (!cdx->mcdi)
115 mcdi = cdx_mcdi_if(cdx);
116 mcdi->cdx = cdx;
118 mcdi->workqueue = alloc_ordered_workqueue("mcdi_wq", 0);
119 if (!mcdi->workqueue)
121 mutex_init(&mcdi->iface_lock);
122 mcdi->mode = MCDI_MODE_EVENTS;
123 INIT_LIST_HEAD(&mcdi->cmd_list);
124 init_waitqueue_head(&mcdi->cmd_complete_wq);
126 mcdi->new_epoch = true;
130 kfree(cdx->mcdi);
131 cdx->mcdi = NULL;
138 struct cdx_mcdi_iface *mcdi;
140 mcdi = cdx_mcdi_if(cdx);
141 if (!mcdi)
146 destroy_workqueue(mcdi->workqueue);
147 kfree(cdx->mcdi);
148 cdx->mcdi = NULL;
151 static bool cdx_mcdi_flushed(struct cdx_mcdi_iface *mcdi, bool ignore_cleanups)
155 mutex_lock(&mcdi->iface_lock);
156 flushed = list_empty(&mcdi->cmd_list) &&
157 (ignore_cleanups || !mcdi->outstanding_cleanups);
158 mutex_unlock(&mcdi->iface_lock);
165 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
167 if (!mcdi)
170 wait_event(mcdi->cmd_complete_wq,
171 cdx_mcdi_flushed(mcdi, false));
177 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
181 if (!mcdi)
184 flush_workqueue(mcdi->workqueue);
186 add_wait_queue(&mcdi->cmd_complete_wq, &wait);
188 while (!cdx_mcdi_flushed(mcdi, true)) {
195 remove_wait_queue(&mcdi->cmd_complete_wq, &wait);
225 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
233 if (!mcdi)
236 mcdi->prev_seq = cmd->seq;
237 mcdi->seq_held_by[cmd->seq] = cmd;
238 mcdi->db_held_by = cmd;
241 not_epoch = !mcdi->new_epoch;
269 mcdi->new_epoch = false;
322 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
325 if (!mcdi)
342 mutex_lock(&mcdi->iface_lock);
343 CDX_WARN_ON_PARANOID(cleanups > mcdi->outstanding_cleanups);
344 all_done = (mcdi->outstanding_cleanups -= cleanups) == 0;
345 mutex_unlock(&mcdi->iface_lock);
347 wake_up(&mcdi->cmd_complete_wq);
351 static void _cdx_mcdi_cancel_cmd(struct cdx_mcdi_iface *mcdi,
357 list_for_each_entry(cmd, &mcdi->cmd_list, list)
366 cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
381 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
384 if (!mcdi)
387 mutex_lock(&mcdi->iface_lock);
388 cdx_mcdi_timeout_cmd(mcdi, cmd, &cleanup_list);
389 mutex_unlock(&mcdi->iface_lock);
493 static bool cdx_mcdi_get_seq(struct cdx_mcdi_iface *mcdi, unsigned char *seq)
495 *seq = mcdi->prev_seq;
497 *seq = (*seq + 1) % ARRAY_SIZE(mcdi->seq_held_by);
498 } while (mcdi->seq_held_by[*seq] && *seq != mcdi->prev_seq);
499 return !mcdi->seq_held_by[*seq];
506 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
509 if (!mcdi) {
514 if (mcdi->mode == MCDI_MODE_FAIL) {
519 cmd->mcdi = mcdi;
527 queue_work(mcdi->workqueue, &cmd->work);
531 static void cdx_mcdi_cmd_start_or_queue(struct cdx_mcdi_iface *mcdi,
534 struct cdx_mcdi *cdx = mcdi->cdx;
537 if (!mcdi->db_held_by &&
538 cdx_mcdi_get_seq(mcdi, &seq)) {
549 static void cdx_mcdi_start_or_queue(struct cdx_mcdi_iface *mcdi,
554 list_for_each_entry_safe(cmd, tmp, &mcdi->cmd_list, list)
557 cdx_mcdi_cmd_start_or_queue(mcdi, cmd);
562 struct cdx_mcdi_iface *mcdi;
572 mcdi = cdx_mcdi_if(cdx);
573 if (!mcdi)
578 mutex_lock(&mcdi->iface_lock);
579 cmd = mcdi->seq_held_by[respseq];
583 mutex_unlock(&mcdi->iface_lock);
588 cdx_mcdi_complete_cmd(mcdi, cmd, outbuf, len, &cleanup_list);
593 mutex_unlock(&mcdi->iface_lock);
595 cdx_mcdi_process_cleanup_list(mcdi->cdx, &cleanup_list);
602 struct cdx_mcdi_iface *mcdi = cmd->mcdi;
604 mutex_lock(&mcdi->iface_lock);
606 cmd->handle = mcdi->prev_handle++;
607 list_add_tail(&cmd->list, &mcdi->cmd_list);
608 cdx_mcdi_cmd_start_or_queue(mcdi, cmd);
610 mutex_unlock(&mcdi->iface_lock);
618 static bool cdx_mcdi_complete_cmd(struct cdx_mcdi_iface *mcdi,
625 struct cdx_mcdi *cdx = mcdi->cdx;
686 if (mcdi->db_held_by == cmd)
687 mcdi->db_held_by = NULL;
699 cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
704 mcdi->seq_held_by[cmd->seq] = NULL;
706 cdx_mcdi_start_or_queue(mcdi, rc != MC_CMD_ERR_QUEUE_FULL);
709 wake_up(&mcdi->cmd_complete_wq);
716 static void cdx_mcdi_timeout_cmd(struct cdx_mcdi_iface *mcdi,
720 struct cdx_mcdi *cdx = mcdi->cdx;
727 cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
817 * Caller must hold the mcdi iface_lock.
821 struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
823 if (!mcdi)
826 mcdi->mode = MCDI_MODE_FAIL;
828 while (!list_empty(&mcdi->cmd_list)) {
831 cmd = list_first_entry(&mcdi->cmd_list, struct cdx_mcdi_cmd,
833 _cdx_mcdi_cancel_cmd(mcdi, cdx_mcdi_cmd_handle(cmd), cleanup_list);