static inline void fdma_handle_fdma_err_irq(struct fdma_channel *channel) { struct fdma *fdma = channel->fdma; void (*err_cb)(unsigned long) = channel->params->err_cb; unsigned long err_cb_parm = channel->params->err_cb_parm; spin_lock(&fdma->channels_lock); /* err is bits 2-4 */ fdma_dbg(fdma, "%s: FDMA error %d on channel %d\n", __FUNCTION__, (readl(CMD_STAT_REG(channel->chan_num)) >> 2) & 0x7, channel->chan_num); /* According to the spec, in case of error transfer "may be * aborted" (or may not be, sigh) so let's make the situation * clear and stop it explicitly now. */ writel(MBOX_CMD_PAUSE_CHANNEL << (channel->chan_num * 2), fdma->io_base + fdma->regs.cmd_set); channel->sw_state = FDMA_STOPPING; spin_unlock(&fdma->channels_lock); wake_up(&channel->dma_chan->wait_queue); if (err_cb) { if (channel->params->err_cb_isr) err_cb(err_cb_parm); else tasklet_schedule(&channel->fdma_error); } }
Config& Config::instance_helper(std::string loc, DupInitCB err_cb) { static std::unique_ptr<Config> cfg; static std::mutex init_mutex; if( !loc.empty() && err_cb != nullptr ) { // Initialize on request bool succeeded; { // scope of lock_guard std::lock_guard<std::mutex> lock(init_mutex); if (cfg != nullptr) { succeeded = false; } else { cfg.reset(new Config(loc)); succeeded = true; } } // lock_guard is released here // error callback after releasing the lock`enter code here` if (!succeeded) err_cb(loc); } if (cfg == nullptr) throw std::logic_error("Requested uninitialized Config"); return *cfg.get(); }
static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), int (*err_cb)(int, void *), void *arg) { struct nlmsghdr *hdr; for (hdr = (struct nlmsghdr *)buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { if (hdr->nlmsg_seq != CR_NLMSG_SEQ) continue; if (hdr->nlmsg_type == NLMSG_DONE) { int *len = (int *)NLMSG_DATA(hdr); if (*len < 0) { pr_err("ERROR %d reported by netlink (%s)\n", *len, strerror(-*len)); return *len; } return 0; } if (hdr->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(hdr); if (hdr->nlmsg_len - sizeof(*hdr) < sizeof(struct nlmsgerr)) { pr_err("ERROR truncated\n"); return -1; } if (err->error == 0) return 0; return err_cb(err->error, arg); } if (cb(hdr, arg)) return -1; } return 1; }