static void cmd_crash_exit_handler(struct mem_link_device *mld)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	unsigned long flags;

	spin_lock_irqsave(&ld->lock, flags);
	ld->state = LINK_STATE_CP_CRASH;
	spin_unlock_irqrestore(&ld->lock, flags);

	if (timer_pending(&mc->crash_ack_timer))
		del_timer(&mc->crash_ack_timer);

	if (atomic_read(&mc->forced_cp_crash))
		evt_log(0, "%s<-%s: CP_CRASH_ACK\n", ld->name, mc->name);
	else
		evt_log(0, "%s<-%s: ERR! CP_CRASH_EXIT\n", ld->name, mc->name);

#ifdef DEBUG_MODEM_IF
	if (!atomic_read(&mc->forced_cp_crash))
		queue_work(system_nrt_wq, &mld->dump_work);
#endif

	mem_handle_cp_crash(mld, STATE_CRASH_EXIT);
}
static void cmd_crash_reset_handler(struct mem_link_device *mld)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	unsigned long flags;

	spin_lock_irqsave(&ld->lock, flags);
	ld->state = LINK_STATE_OFFLINE;
	spin_unlock_irqrestore(&ld->lock, flags);

	evt_log(0, "%s<-%s: ERR! CP_CRASH_RESET\n", ld->name, mc->name);

	mem_handle_cp_crash(mld, STATE_CRASH_RESET);
}
/**
@brief		print a snapshot of the status of a memory interface

@param mld	the pointer to a mem_link_device instance
@param mst	the pointer to a mem_snapshot instance
*/
void print_mem_snapshot(struct mem_link_device *mld, struct mem_snapshot *mst)
{
#ifdef DEBUG_MODEM_IF
	struct link_device *ld = &mld->link_dev;

	evt_log(0, "%s: [%s] ACC{%X %d} FMT{TI:%u TO:%u RI:%u RO:%u} "
		"RAW{TI:%u TO:%u RI:%u RO:%u} INTR{RX:0x%X TX:0x%X}\n",
		ld->name, ipc_dir(mst->dir), mst->magic, mst->access,
		mst->head[IPC_FMT][TX], mst->tail[IPC_FMT][TX],
		mst->head[IPC_FMT][RX], mst->tail[IPC_FMT][RX],
		mst->head[IPC_RAW][TX], mst->tail[IPC_RAW][TX],
		mst->head[IPC_RAW][RX], mst->tail[IPC_RAW][RX],
		mst->int2ap, mst->int2cp);
#endif
}
/**
@brief		print a snapshot of the status of a circular queue

@param mld	the pointer to a mem_link_device instance
@param mst	the pointer to a mem_snapshot instance
@param dev	the pointer to a mem_ipc_device instance (IPC_FMT, etc.)
*/
void print_dev_snapshot(struct mem_link_device *mld, struct mem_snapshot *mst,
			struct mem_ipc_device *dev)
{
#ifdef DEBUG_MODEM_IF
	struct link_device *ld = &mld->link_dev;
	enum dev_format id = dev->id;

	if (id > IPC_RAW)
		return;

	evt_log(0, "%s: [%s] %s | TXQ{in:%u out:%u} RXQ{in:%u out:%u} | "
		"INTR{0x%02X}\n",
		ld->name, ipc_dir(mst->dir), dev->name,
		mst->head[id][TX], mst->tail[id][TX],
		mst->head[id][RX], mst->tail[id][RX],
		(mst->dir == RX) ? mst->int2ap : mst->int2cp);
#endif
}
/**
@brief		print a REQ_ACK

Prints a snapshot of the status of the @b @@dev circular queue when AP sends or
receives an REQ_ACK.

@param mld	the pointer to a mem_link_device instance
@param mst	the pointer to a mem_snapshot instance
@param dev	the pointer to a mem_ipc_device instance (IPC_FMT, etc.)
@param dir	the direction of communication (TX or RX)
*/
void print_req_ack(struct mem_link_device *mld, struct mem_snapshot *mst,
		   struct mem_ipc_device *dev, enum direction dir)
{
#ifdef DEBUG_MODEM_IF_FLOW_CTRL
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	enum dev_format id = dev->id;
	unsigned int qsize = get_size(cq(dev, dir));
	unsigned int in = mst->head[id][dir];
	unsigned int out = mst->tail[id][dir];
	unsigned int usage = circ_get_usage(qsize, in, out);
	unsigned int space = circ_get_space(qsize, in, out);

	evt_log(0, "REQ_ACK: %s%s%s: %s_%s.%d "
		"{in:%u out:%u usage:%u space:%u}\n",
		ld->name, arrow(dir), mc->name, dev->name, q_dir(dir),
		dev->req_ack_cnt[dir], in, out, usage, space);
#endif
}
static void print_pm_status(struct mem_link_device *mld)
{
#ifdef DEBUG_MODEM_IF
	struct link_device *ld = &mld->link_dev;
	unsigned int magic;
	int ap_wakeup;
	int ap_status;
	int cp_wakeup;
	int cp_status;

	magic = get_magic(mld);
	ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup);
	ap_status = gpio_get_value(mld->gpio_ap_status);
	cp_wakeup = gpio_get_value(mld->gpio_cp_wakeup);
	cp_status = gpio_get_value(mld->gpio_cp_status);

	/*
	** PM {ap_wakeup:cp_wakeup:cp_status:ap_status:magic} <CALLER>
	*/
	evt_log(0, "%s: PM {%d:%d:%d:%d:%X} <%pf>\n", ld->name,
		ap_wakeup, cp_wakeup, cp_status, ap_status, magic, CALLER);
#endif
}
void print_pm_status(struct mem_link_device *mld)
{
#if defined(DEBUG_MODEM_IF) && defined(CONFIG_LINK_POWER_MANAGEMENT)
	struct link_device *ld = &mld->link_dev;
	unsigned int magic;
	int ap_wakeup;
	int ap_status;
	int cp_wakeup;
	int cp_status;

	magic = get_magic(mld);
	ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup);
	ap_status = gpio_get_value(mld->gpio_ap_status);
	cp_wakeup = gpio_get_value(mld->gpio_cp_wakeup);
	cp_status = gpio_get_value(mld->gpio_cp_status);

	/*
	** PM {ap_wakeup:cp_wakeup:cp_status:ap_status:magic} <CALLER>
	*/
	evt_log(0, "%s: PM {%d:%d:%d:%d:%X} %d <%pf>\n", ld->name,
		ap_wakeup, cp_wakeup, cp_status, ap_status, magic,
		atomic_read(&mld->ref_cnt), CALLER);
#endif
}
Example #8
0
int
main(void)
{
  EVTCONTEXT *ctx;
  EVTREC *e;
  char *es;
  
  ctx = evt_ctx_init("evtfmt", LOG_AUTH);
  e = evt_rec_init(ctx, LOG_INFO, "Test message with an embedded ';' in it. It also contains an <XML> like tag.");
  evt_rec_add_tags(e, 
                   evt_tag_str("test:tag", "'value'"),
                   evt_tag_str("test:tag2", "\n\n\n\n"),
                   evt_tag_int("test:fd", fileno(stderr)),
                   evt_tag_errno("test:error", EAGAIN),
                   evt_tag_printf("test:printf", "%d %d", 5, 6),
                   NULL);
  
  es = evt_format(e);
  printf("%s\n", es);
  free(es);
  
  evt_log(e);
  return 0;
}
static void lli_link_off(struct link_device *ld)
{
	evt_log(0, "%s: PM %s <%pf>\n", ld->name, FUNC, CALLER);
	stop_pm(ld_to_mem_link_device(ld));
	mipi_lli_reload();
}
static void lli_link_reload(struct link_device *ld)
{
	evt_log(0, "%s: PM %s <%pf>\n", ld->name, FUNC, CALLER);
	mipi_lli_reload();
}
/**
@brief		trigger an enforced CP crash

@param mld	the pointer to a mem_link_device instance
*/
void mem_forced_cp_crash(struct mem_link_device *mld)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	unsigned long flags;
	bool duplicated = false;
#ifdef DEBUG_MODEM_IF
	struct utc_time t;
#endif

#ifdef DEBUG_MODEM_IF
	get_utc_time(&t);
#endif

	/* Disable normal IPC */
	set_magic(mld, MEM_CRASH_MAGIC);
	set_access(mld, 0);

	spin_lock_irqsave(&mld->lock, flags);
	if (mld->forced_cp_crash)
		duplicated = true;
	else
		mld->forced_cp_crash = true;
	spin_unlock_irqrestore(&mld->lock, flags);

	if (duplicated) {
#ifdef DEBUG_MODEM_IF
		evt_log(HMSU_FMT " %s: %s: ALREADY in progress <%pf>\n",
			t.hour, t.min, t.sec, t.us, CALLEE, ld->name, CALLER);
#endif
		return;
	}

	if (!cp_online(mc)) {
#ifdef DEBUG_MODEM_IF
		evt_log(HMSU_FMT " %s: %s: %s.state %s != ONLINE <%pf>\n",
			t.hour, t.min, t.sec, t.us,
			CALLEE, ld->name, mc->name, mc_state(mc), CALLER);
#endif
		return;
	}

	if (!wake_lock_active(&mld->dump_wlock))
		wake_lock(&mld->dump_wlock);

	stop_net_ifaces(ld);

	/**
	 * If there is no CRASH_ACK from a CP in FORCE_CRASH_ACK_TIMEOUT,
	 * handle_no_cp_crash_ack() will be executed.
	 */
	mif_add_timer(&mld->crash_ack_timer, FORCE_CRASH_ACK_TIMEOUT,
		      handle_no_cp_crash_ack, (unsigned long)mld);

	/* Send CRASH_EXIT command to a CP */
	send_ipc_irq(mld, cmd2int(CMD_CRASH_EXIT));

#ifdef DEBUG_MODEM_IF
	evt_log(HMSU_FMT " CRASH_EXIT: %s->%s: CP_CRASH_REQ <by %pf>\n",
		t.hour, t.min, t.sec, t.us, ld->name, mc->name, CALLER);

	if (in_interrupt())
		queue_work(system_nrt_wq, &mld->dump_work);
	else
		save_mem_dump(mld);
#endif
}
static struct sk_buff *rxq_read(struct mem_link_device *mld,
				struct mem_ipc_device *dev,
				unsigned int in)
{
	struct link_device *ld = &mld->link_dev;
	struct sk_buff *skb;
	char *src = get_rxq_buff(dev);
	unsigned int qsize = get_rxq_buff_size(dev);
	unsigned int out = get_rxq_tail(dev);
	unsigned int rest = circ_get_usage(qsize, in, out);
	unsigned int len;
	char hdr[SIPC5_MIN_HEADER_SIZE];

	/* Copy the header in a frame to the header buffer */
	circ_read(hdr, src, qsize, out, SIPC5_MIN_HEADER_SIZE);

	/* Check the config field in the header */
	if (unlikely(!sipc5_start_valid(hdr))) {
		mif_err("%s: ERR! %s BAD CFG 0x%02X (in:%d out:%d rest:%d)\n",
			ld->name, dev->name, hdr[SIPC5_CONFIG_OFFSET],
			in, out, rest);
		goto bad_msg;
	}

	/* Verify the length of the frame (data + padding) */
	len = sipc5_get_total_len(hdr);
	if (unlikely(len > rest)) {
		mif_err("%s: ERR! %s BAD LEN %d > rest %d\n",
			ld->name, dev->name, len, rest);
		goto bad_msg;
	}

	/* Allocate an skb */
	skb = mem_alloc_skb(len);
	if (!skb) {
		mif_err("%s: ERR! %s mem_alloc_skb(%d) fail\n",
			ld->name, dev->name, len);
		goto no_mem;
	}

	/* Read the frame from the RXQ */
	circ_read(skb_put(skb, len), src, qsize, out, len);

	/* Update tail (out) pointer to the frame to be read in the future */
	set_rxq_tail(dev, circ_new_ptr(qsize, out, len));

	/* Finish reading data before incrementing tail */
	smp_mb();

#ifdef DEBUG_MODEM_IF
	/* Record the time-stamp */
	getnstimeofday(&skbpriv(skb)->ts);
#endif

	return skb;

bad_msg:
	evt_log(0, "%s: %s%s%s: ERR! BAD MSG: %02x %02x %02x %02x\n",
		FUNC, ld->name, arrow(RX), ld->mc->name,
		hdr[0], hdr[1], hdr[2], hdr[3]);
	set_rxq_tail(dev, in);	/* Reset tail (out) pointer */
	mem_forced_cp_crash(mld);

no_mem:
	return NULL;
}
void mem_forced_cp_crash(struct mem_link_device *mld)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	bool duplicated = false;
	unsigned long flags;

	/* Disable normal IPC */
	set_magic(mld, MEM_CRASH_MAGIC);
	set_access(mld, 0);

	spin_lock_irqsave(&mld->lock, flags);
	if (atomic_read(&mc->forced_cp_crash))
		duplicated = true;
	else
		atomic_set(&mc->forced_cp_crash, 1);
	spin_unlock_irqrestore(&mld->lock, flags);

	if (duplicated) {
		evt_log(0, "%s: %s: ALREADY in progress <%pf>\n",
			FUNC, ld->name, CALLER);
		return;
	}

	if (!cp_online(mc)) {
		evt_log(0, "%s: %s: %s.state %s != ONLINE <%pf>\n",
			FUNC, ld->name, mc->name, mc_state(mc), CALLER);
		return;
	}

	if (mc->wake_lock) {
		if (!wake_lock_active(mc->wake_lock)) {
			wake_lock(mc->wake_lock);
			mif_err("%s->wake_lock locked\n", mc->name);
		}
	}

	if (mld->attrs & LINK_ATTR(LINK_ATTR_MEM_DUMP)) {
		stop_net_ifaces(ld);

		if (mld->debug_info)
			mld->debug_info();

		/**
		 * If there is no CRASH_ACK from CP in a timeout,
		 * handle_no_cp_crash_ack() will be executed.
		 */
		mif_add_timer(&mc->crash_ack_timer, FORCE_CRASH_ACK_TIMEOUT,
			      handle_no_cp_crash_ack, (unsigned long)mld);

		/* Send CRASH_EXIT command to a CP */
		send_ipc_irq(mld, cmd2int(CMD_CRASH_EXIT));
	} else {
		modemctl_notify_event(MDM_EVENT_CP_FORCE_CRASH);
	}

	evt_log(0, "%s->%s: CP_CRASH_REQ <%pf>\n", ld->name, mc->name, CALLER);

#ifdef DEBUG_MODEM_IF
	if (in_interrupt())
		queue_work(system_nrt_wq, &mld->dump_work);
	else
		save_mem_dump(mld);
#endif
}