/** * iwl_print_event_log - Dump error event log to syslog * */ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, u32 num_events, u32 mode, int pos, char **buf, size_t bufsz) { u32 i; u32 base; /* SRAM byte address of event log header */ u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ u32 ptr; /* SRAM byte address of log data */ u32 ev, time, data; /* event log data */ unsigned long reg_flags; struct iwl_priv *priv = priv(trans); if (num_events == 0) return pos; base = priv->device_pointers.log_event_table; if (priv->ucode_type == IWL_UCODE_INIT) { if (!base) base = priv->init_evtlog_ptr; } else { if (!base) base = priv->inst_evtlog_ptr; } if (mode == 0) event_size = 2 * sizeof(u32); else event_size = 3 * sizeof(u32); ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* Make sure device is powered up for SRAM reads */ spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); iwl_grab_nic_access(bus(trans)); /* Set starting address; reads will auto-increment */ iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOG:0x%08x:%04u\n", time, ev); } else { trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", time, ev); } } else { data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); } else { IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); trace_iwlwifi_dev_ucode_event(priv, time, data, ev); } } } /* Allow device to power down */ iwl_release_nic_access(bus(trans)); spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); return pos; }
static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, u32 num_events, u32 mode, int pos, char **buf, size_t bufsz) { u32 i; u32 base; /* */ u32 event_size; /* */ u32 ptr; /* */ u32 ev, time, data; /* */ unsigned long reg_flags; if (num_events == 0) return pos; base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { if (!base) base = trans->shrd->fw->init_evtlog_ptr; } else { if (!base) base = trans->shrd->fw->inst_evtlog_ptr; } if (mode == 0) event_size = 2 * sizeof(u32); else event_size = 3 * sizeof(u32); ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* */ spin_lock_irqsave(&trans->reg_lock, reg_flags); if (unlikely(!iwl_grab_nic_access(trans))) goto out_unlock; /* */ iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); /* */ for (i = 0; i < num_events; i++) { ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT); time = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (mode == 0) { /* */ if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOG:0x%08x:%04u\n", time, ev); } else { trace_iwlwifi_dev_ucode_event(trans->dev, 0, time, ev); IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", time, ev); } } else { data = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); } else { IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); trace_iwlwifi_dev_ucode_event(trans->dev, time, data, ev); } } } /* */ iwl_release_nic_access(trans); out_unlock: spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; }